* MIPS/ELF linker
@ 1999-07-31 14:49 Ralf Baechle
1999-07-31 15:26 ` Mark Mitchell
0 siblings, 1 reply; 10+ messages in thread
From: Ralf Baechle @ 1999-07-31 14:49 UTC (permalink / raw)
To: binutils, Tim Hockin
Starting to play with the new MIPS backend from CVS:
[ralf@lappi binutils]$ cat x.s
.text
.globl __start
.weak hurz
__start:
la $2,hurz
[ralf@lappi binutils]$ mips-linux-as -O3 -KPIC -o x.o x.s
[ralf@lappi binutils]$ mips-linux-ld -o x x.o
x.o(.text+0x0): undefined reference to `hurz'
mips-linux-ld: x.o: .text+0x0: jump to stub routine which is not jal
mips-linux-ld: final link failed: Bad value
[ralf@lappi binutils]$
Misshandling error the weak undefined reference prevents any linking
against GNU libc since crti.o has a weak undefined reference against
__gmon_start__. A fix for elf32-mips.c is appended below.
The ``jump to stub routine which is not jal'' error message which is
obviously bogus as well is caused by mips_elf_calculate_relocation
returning without setting *require_jalxp to a defined value. A patch
to initialize the variable at the beginning of the function is also
part of the elf32-mips.c patch below.
A third bug is triggered by attempting to link an arbitrary program like
``main(){}'' against glibc 2.0. This results in a large number of
/usr/bin/mips-linux-ld: not enough GOT space for local GOT entries
messages. Obviously the calculation of the GOT size is wrong, but I'm
not yet shure what's the problem, so I just report this without a fix.
Bug #4:
[ralf@lappi bfd]$ cat y.s
.text
foo: la $2,foo
[ralf@lappi bfd]$ mips-linux-as -O3 -KPIC -o y.o y.s
[ralf@lappi bfd]$ mips-linux-ld -o y y.o
Segmentation fault (core dumped)
[ralf@lappi bfd]$
This is caused by g->global_gotsym in elf32-mips.c:7896
i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
being NULL; I also don't have a fix for this one.
Ralf
--- elf32-mips.c-cygnus Sat Jul 31 12:23:43 1999
+++ elf32-mips.c Sat Jul 31 23:02:33 1999
@@ -5791,6 +5791,9 @@
/* Assume that there will be no overflow. */
overflowed_p = false;
+ /* Assume no jalx is required */
+ *require_jalxp = false;
+
/* Figure out whether or not the symbol is local, and get the offset
used in the array of hash table entries. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -5870,6 +5873,12 @@
else
symbol = h->root.root.u.def.value;
}
+ else if ((h->root.root.type == bfd_link_hash_undefweak)
+ || (info->shared && !info->symbolic && !info->no_undefined))
+ {
+ sec = bfd_und_section_ptr;
+ symbol = 0;
+ }
else
{
(*info->callbacks->undefined_symbol)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-07-31 14:49 MIPS/ELF linker Ralf Baechle
@ 1999-07-31 15:26 ` Mark Mitchell
1999-07-31 16:23 ` Ralf Baechle
0 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1999-07-31 15:26 UTC (permalink / raw)
To: ralf; +Cc: binutils, thockin
Thanks for trying the MIPS backend out. I'm eager to shake out the
bugs. It seems pretty solid on IRIX6, now, but I'm sure there are
issues remaining on other platforms.
+ /* Assume no jalx is required */
+ *require_jalxp = false;
+
REQUIRE_JALXP is set unconditionally a few lines down. Why doesn't
that do the trick? The caller should not be looking at the value of
require_jalx unless calculate_relocation returns a successful error
code.
@@ -5870,6 +5873,12 @@
else
symbol = h->root.root.u.def.value;
}
+ else if ((h->root.root.type == bfd_link_hash_undefweak)
+ || (info->shared && !info->symbolic && !info->no_undefined))
+ {
+ sec = bfd_und_section_ptr;
+ symbol = 0;
+ }
else
{
(*info->callbacks->undefined_symbol)
This looks right to me. I thought I had already fixed this, but I
guess not. Ian should give final approval, of course.
/usr/bin/mips-linux-ld: not enough GOT space for local GOT entries
Probably some relocation is requiring a local GOT entry, but we're not
allocating it. Look for this code in check_relocs:
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
|| r_type == R_MIPS_GOT_DISP))
{
/* We may need a local GOT entry for this relocation. We
don't count R_MIPS_HI16 or R_MIPS_GOT16 relocations
because they are always followed by a R_MIPS_LO16
relocation for the value. We don't R_MIPS_GOT_PAGE
because we can estimate the maximum number of pages
needed by looking at the size of the segment.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
conservative, we could actually build the GOT here,
rather than in relocate_section. */
g->local_gotno++;
sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
}
Probably this code is not firing in some case where it should be
firing. Therefore, we're not adding enough GOT space. That might
help track down the bug.
If not, feel free to send me the files on your link-line in a giant
tar-ball, together with how your configuring binutils, and I'll try to
duplicate and fix your problem.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-07-31 15:26 ` Mark Mitchell
@ 1999-07-31 16:23 ` Ralf Baechle
1999-07-31 16:41 ` Mark Mitchell
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Ralf Baechle @ 1999-07-31 16:23 UTC (permalink / raw)
To: Mark Mitchell; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips
On Sat, Jul 31, 1999 at 03:28:42PM -0700, Mark Mitchell wrote:
> Thanks for trying the MIPS backend out. I'm eager to shake out the
> bugs. It seems pretty solid on IRIX6, now, but I'm sure there are
> issues remaining on other platforms.
>
> + /* Assume no jalx is required */
> + *require_jalxp = false;
> +
>
> REQUIRE_JALXP is set unconditionally a few lines down. Why doesn't
> that do the trick? The caller should not be looking at the value of
> require_jalx unless calculate_relocation returns a successful error
> code.
So the caller _bfd_mips_elf_relocate_section does not behave appropriately
when mips_elf_calculate_relocation returns bfd_reloc_undefined. Search
for bfd_reloc_undefined in mips_elf_calculate_relocation; it's being
returned before an actual value gets assigned to *require_jalxp.
> /usr/bin/mips-linux-ld: not enough GOT space for local GOT entries
>
> Probably some relocation is requiring a local GOT entry, but we're not
> allocating it. Look for this code in check_relocs:
>
> if (!h && (r_type == R_MIPS_CALL_LO16
> || r_type == R_MIPS_GOT_LO16
> || r_type == R_MIPS_GOT_DISP))
> {
> /* We may need a local GOT entry for this relocation. We
> don't count R_MIPS_HI16 or R_MIPS_GOT16 relocations
> because they are always followed by a R_MIPS_LO16
> relocation for the value. We don't R_MIPS_GOT_PAGE
> because we can estimate the maximum number of pages
> needed by looking at the size of the segment.
>
> This estimation is very conservative since we can merge
> duplicate entries in the GOT. In order to be less
> conservative, we could actually build the GOT here,
> rather than in relocate_section. */
> g->local_gotno++;
> sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
> }
>
> Probably this code is not firing in some case where it should be
> firing. Therefore, we're not adding enough GOT space. That might
> help track down the bug.
>
> If not, feel free to send me the files on your link-line in a giant
> tar-ball, together with how your configuring binutils, and I'll try to
> duplicate and fix your problem.
I'll send you a non-giant tarball of 73kb which will demonstrate the
problem. Just run the Makefile in the archive. The linker has been
configured for the target mips-linux which is a standard MIPS/ELF target.
Ralf
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-07-31 16:23 ` Ralf Baechle
@ 1999-07-31 16:41 ` Mark Mitchell
1999-07-31 16:46 ` Ralf Baechle
1999-08-01 14:01 ` Mark Mitchell
1999-08-01 14:03 ` Mark Mitchell
2 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1999-07-31 16:41 UTC (permalink / raw)
To: ralf; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips
Ralf --
Thanks for the tarball. I'll not be able to look at this until
tomorrow, but I will do so then.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-07-31 16:41 ` Mark Mitchell
@ 1999-07-31 16:46 ` Ralf Baechle
0 siblings, 0 replies; 10+ messages in thread
From: Ralf Baechle @ 1999-07-31 16:46 UTC (permalink / raw)
To: Mark Mitchell; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips
On Sat, Jul 31, 1999 at 04:42:37PM -0700, Mark Mitchell wrote:
> Ralf --
>
> Thanks for the tarball. I'll not be able to look at this until
> tomorrow, but I will do so then.
Ok, I'm looking into things in parallel if I find the time. I'll also
try to rebuild GNU libc for MIPS. That has historically proven to be
a bone breaker for ld. The last time I tried a few weeks ago I got
~500 assertion messages from ld just alone for the libc final link ...
Will let you know how things go.
Ralf
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-07-31 16:23 ` Ralf Baechle
1999-07-31 16:41 ` Mark Mitchell
@ 1999-08-01 14:01 ` Mark Mitchell
1999-08-03 9:29 ` Ian Lance Taylor
1999-08-01 14:03 ` Mark Mitchell
2 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1999-08-01 14:01 UTC (permalink / raw)
To: ralf; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips
I've checked in the following patch to elf32-mips.c to fix these
problems.
Ian, I'd like your comments on a couple of other issues. In auditing
the current code vs. the pre-IRIX6 modifications I see that this hunk
in the current code is not preserved:
else if (info->shared && !info->symbolic && !info->no_undefined)
relocation = 0;
else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0)
{
/* If this is a dynamic link, we should have created
a _DYNAMIC_LINK symbol in
mips_elf_create_dynamic_sections. Otherwise, we
should define the symbol with a value of 0.
FIXME: It should probably get into the symbol
table somehow as well. */
BFD_ASSERT (! info->shared);
BFD_ASSERT (bfd_get_section_by_name (output_bfd,
".dynamic") == NULL);
relocation = 0;
}
I don't see the point of the first line (in the context of the new
code). I think that when building a shared library, a relocation
against an undefined symbol should simply be copied into the output
file (adjust as necessary); there's no need to actually perform any
relocation. So, there's no need to give values to undefined symbols.
Therefore, we don't call calculate_relocation in this case at all. If
you think that's wrong, please let me know.
I'm also unsure about the _DYNAMIC_LINK bit. On the one hand, it
would seem that this should be defined in the linker-script if it's
needed? For instance, it would seem to be a bug if an IRIX6
executable happened to use the symbol _DYNAMIC_LINK without a
definition, but then linked successfully because we created this
symbol "by magic".
But, leaving that issue aside, we define this on all systems, in the
non-shared case, in _bfd_mips_elf_create_dynamic_sections. So, I
don't think we need to handle this symbol specially when we perform
relocations against it. Do you agree?
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-08-01 Mark Mitchell <mark@codesourcery.com>
* elf32-mips.c (mips_elf_calculate_relocation): Undefined weak
symbols are considered to have the value zero.
(_bfd_mips_elf_relocate_section): Don't try to perform a
relocation for an undefined symbol.
(_bfd_mips_elf_check_relocs): Allocate locate GOT space for local
GOT16 relocations.
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.36
diff -c -p -r1.36 elf32-mips.c
*** elf32-mips.c 1999/07/29 22:20:26 1.36
--- elf32-mips.c 1999/08/01 20:47:18
*************** mips_elf_calculate_relocation (abfd,
*** 5870,5875 ****
--- 5870,5881 ----
else
symbol = h->root.root.u.def.value;
}
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ /* We allow relocations against undefined weak symbols, giving
+ it the value zero, so that you can undefined weak functions
+ and check to see if they exist by looking at their
+ addresses. */
+ symbol = 0;
else
{
(*info->callbacks->undefined_symbol)
*************** _bfd_mips_elf_relocate_section (output_b
*** 6637,6644 ****
case bfd_reloc_undefined:
/* mips_elf_calculate_relocation already called the
! undefined_symbol callback. */
! break;
case bfd_reloc_notsupported:
abort ();
--- 6643,6652 ----
case bfd_reloc_undefined:
/* mips_elf_calculate_relocation already called the
! undefined_symbol callback. There's no real point in
! trying to perform the relocation at this point, so we
! just skip ahead to the next relocation. */
! continue;
case bfd_reloc_notsupported:
abort ();
*************** _bfd_mips_elf_check_relocs (abfd, info,
*** 7331,7344 ****
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
! || r_type == R_MIPS_GOT_DISP))
{
/* We may need a local GOT entry for this relocation. We
! don't count R_MIPS_HI16 or R_MIPS_GOT16 relocations
! because they are always followed by a R_MIPS_LO16
! relocation for the value. We don't R_MIPS_GOT_PAGE
! because we can estimate the maximum number of pages
! needed by looking at the size of the segment.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
--- 7339,7353 ----
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
! || r_type == R_MIPS_GOT_DISP
! || r_type == R_MIPS_GOT16))
{
/* We may need a local GOT entry for this relocation. We
! don't count R_MIPS_GOT_PAGE because we can estimate the
! maximum number of pages needed by looking at the size of
! the segment. We don't count R_MIPS_GOT_HI16, or
! R_MIPS_CALL_HI16 because these are always followed by an
! R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-07-31 16:23 ` Ralf Baechle
1999-07-31 16:41 ` Mark Mitchell
1999-08-01 14:01 ` Mark Mitchell
@ 1999-08-01 14:03 ` Mark Mitchell
2 siblings, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 1999-08-01 14:03 UTC (permalink / raw)
To: ralf; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips
Ralf sent me another test-case in private email that pointed up a
problem in the way that we were handling relocations when there are
both REL and RELA relocations for a single section. The bottom line
is that the attempt I took at a conservative approach (allocating too
many relocations and then ignoring some of them) is ugly; this patch
attempts to fix that problem, and seems to fix Ralf's test-case.
OK to check in?
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-08-01 Mark Mitchell <mark@codesourcery.com>
* elflink.h (elf_link_size_reloc_section): Use the counts in the
elf-section data to allocate just the right amount of relocation
space. Don't allocate the hash space twice.
(elf_bfd_final_link): Calculate the amount of space to allocate in
each relocation section.
Index: elflink.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
retrieving revision 1.21
diff -c -p -r1.21 elflink.h
*** elflink.h 1999/07/30 21:34:44 1.21
--- elflink.h 1999/08/01 20:47:14
*************** elf_link_size_reloc_section (abfd, rel_h
*** 3761,3794 ****
asection *o;
{
register struct elf_link_hash_entry **p, **pend;
! /* We are overestimating the size required for the relocation
! sections, in the case that we are using both REL and RELA
! relocations for a single section. In that case, RELOC_COUNT will
! be the total number of relocations required, and we allocate
! space for that many REL relocations as well as that many RELA
! relocations. This approximation is wasteful of disk space.
! However, until we keep track of how many of each kind of
! relocation is required, it's difficult to calculate the right
! value. */
! rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count;
/* The contents field must last into write_object_contents, so we
allocate it with bfd_alloc rather than malloc. */
rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
- return false;
-
- p = ((struct elf_link_hash_entry **)
- bfd_malloc (o->reloc_count
- * sizeof (struct elf_link_hash_entry *)));
- if (p == NULL && o->reloc_count != 0)
return false;
!
! elf_section_data (o)->rel_hashes = p;
! pend = p + o->reloc_count;
! for (; p < pend; p++)
! *p = NULL;
return true;
}
--- 3761,3798 ----
asection *o;
{
register struct elf_link_hash_entry **p, **pend;
+ unsigned reloc_count;
! /* Figure out how many relocations there will be. */
! if (rel_hdr == &elf_section_data (o)->rel_hdr)
! reloc_count = elf_section_data (o)->rel_count;
! else
! reloc_count = elf_section_data (o)->rel_count2;
!
! /* That allows us to calculate the size of the section. */
! rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
/* The contents field must last into write_object_contents, so we
allocate it with bfd_alloc rather than malloc. */
rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
return false;
!
! /* We only allocate one set of hash entries, so we only do it the
! first time we are called. */
! if (elf_section_data (o)->rel_hashes == NULL)
! {
! p = ((struct elf_link_hash_entry **)
! bfd_malloc (o->reloc_count
! * sizeof (struct elf_link_hash_entry *)));
! if (p == NULL && o->reloc_count != 0)
! return false;
!
! elf_section_data (o)->rel_hashes = p;
! pend = p + o->reloc_count;
! for (; p < pend; p++)
! *p = NULL;
! }
return true;
}
*************** elf_bfd_final_link (abfd, info)
*** 3997,4002 ****
--- 4001,4030 ----
if (! _bfd_elf_compute_section_file_positions (abfd, info))
goto error_return;
+ /* Figure out how many relocations we will have in each section.
+ Just using RELOC_COUNT isn't good enough since that doesn't
+ maintain a separate value for REL vs. RELA relocations. */
+ if (info->relocateable)
+ for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+ for (o = sub->sections; o != NULL; o = o->next)
+ {
+ asection* output_section = o->output_section;
+
+ if (output_section && (o->flags & SEC_RELOC) != 0)
+ {
+ struct bfd_elf_section_data *esdi
+ = elf_section_data (o);
+ struct bfd_elf_section_data *esdo
+ = elf_section_data (output_section);
+
+ esdo->rel_count += (esdi->rel_hdr.sh_size
+ / esdi->rel_hdr.sh_entsize);
+ if (esdi->rel_hdr2)
+ esdo->rel_count2 += (esdi->rel_hdr2->sh_size
+ / esdi->rel_hdr2->sh_entsize);
+ }
+ }
+
/* That created the reloc sections. Set their sizes, and assign
them file positions, and allocate some buffers. */
for (o = abfd->sections; o != NULL; o = o->next)
*************** elf_bfd_final_link (abfd, info)
*** 4014,4019 ****
--- 4042,4052 ----
o))
goto error_return;
}
+
+ /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
+ to count upwards while actually outputting the relocations. */
+ elf_section_data (o)->rel_count = 0;
+ elf_section_data (o)->rel_count2 = 0;
}
_bfd_elf_assign_file_positions_for_relocs (abfd);
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.36
diff -c -p -r1.36 elf32-mips.c
*** elf32-mips.c 1999/07/29 22:20:26 1.36
--- elf32-mips.c 1999/08/01 20:47:18
*************** mips_elf_calculate_relocation (abfd,
*** 5870,5875 ****
--- 5870,5881 ----
else
symbol = h->root.root.u.def.value;
}
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ /* We allow relocations against undefined weak symbols, giving
+ it the value zero, so that you can undefined weak functions
+ and check to see if they exist by looking at their
+ addresses. */
+ symbol = 0;
else
{
(*info->callbacks->undefined_symbol)
*************** _bfd_mips_elf_relocate_section (output_b
*** 6637,6644 ****
case bfd_reloc_undefined:
/* mips_elf_calculate_relocation already called the
! undefined_symbol callback. */
! break;
case bfd_reloc_notsupported:
abort ();
--- 6643,6652 ----
case bfd_reloc_undefined:
/* mips_elf_calculate_relocation already called the
! undefined_symbol callback. There's no real point in
! trying to perform the relocation at this point, so we
! just skip ahead to the next relocation. */
! continue;
case bfd_reloc_notsupported:
abort ();
*************** _bfd_mips_elf_check_relocs (abfd, info,
*** 7331,7344 ****
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
! || r_type == R_MIPS_GOT_DISP))
{
/* We may need a local GOT entry for this relocation. We
! don't count R_MIPS_HI16 or R_MIPS_GOT16 relocations
! because they are always followed by a R_MIPS_LO16
! relocation for the value. We don't R_MIPS_GOT_PAGE
! because we can estimate the maximum number of pages
! needed by looking at the size of the segment.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
--- 7339,7353 ----
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
! || r_type == R_MIPS_GOT_DISP
! || r_type == R_MIPS_GOT16))
{
/* We may need a local GOT entry for this relocation. We
! don't count R_MIPS_GOT_PAGE because we can estimate the
! maximum number of pages needed by looking at the size of
! the segment. We don't count R_MIPS_GOT_HI16, or
! R_MIPS_CALL_HI16 because these are always followed by an
! R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-08-01 14:01 ` Mark Mitchell
@ 1999-08-03 9:29 ` Ian Lance Taylor
1999-08-03 9:46 ` Mark Mitchell
1999-08-03 9:48 ` Mark Mitchell
0 siblings, 2 replies; 10+ messages in thread
From: Ian Lance Taylor @ 1999-08-03 9:29 UTC (permalink / raw)
To: mark; +Cc: ralf, ralf, binutils, thockin, linux, linux-mips, linux-mips
From: Mark Mitchell <mark@codesourcery.com>
Date: Sun, 01 Aug 1999 14:03:27 -0700
Ian, I'd like your comments on a couple of other issues. In auditing
the current code vs. the pre-IRIX6 modifications I see that this hunk
in the current code is not preserved:
else if (info->shared && !info->symbolic && !info->no_undefined)
relocation = 0;
else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0)
{
/* If this is a dynamic link, we should have created
a _DYNAMIC_LINK symbol in
mips_elf_create_dynamic_sections. Otherwise, we
should define the symbol with a value of 0.
FIXME: It should probably get into the symbol
table somehow as well. */
BFD_ASSERT (! info->shared);
BFD_ASSERT (bfd_get_section_by_name (output_bfd,
".dynamic") == NULL);
relocation = 0;
}
I don't see the point of the first line (in the context of the new
code). I think that when building a shared library, a relocation
against an undefined symbol should simply be copied into the output
file (adjust as necessary); there's no need to actually perform any
relocation. So, there's no need to give values to undefined symbols.
Therefore, we don't call calculate_relocation in this case at all. If
you think that's wrong, please let me know.
When I read your paragraph above, it makes sense. However, when I
look at the current code, I think that calculate_relocation will get
called for a reference to an undefined symbol from a shared library.
If you are proposing a different patch, to simply copy shared library
relocations against undefined symbols rather than to perform the
relocation, then I think that will indeed work correctly. But note
that you do have to handle the info->symbolic and info->no_undefined
cases. Something like the above code seems like a simple way to
handle all the cases.
I'm also unsure about the _DYNAMIC_LINK bit. On the one hand, it
would seem that this should be defined in the linker-script if it's
needed? For instance, it would seem to be a bug if an IRIX6
executable happened to use the symbol _DYNAMIC_LINK without a
definition, but then linked successfully because we created this
symbol "by magic".
Since this symbol is in the reserved name space, it's OK for the
linker to define it magically. It's no more buggy for an executable
to use the symbol _DYNAMIC_LINK without a definition than it is for an
executable to use the symbol __program_header_table without a
definition.
This change was from Kazumoto Kojima; I assume that on some systems
_DYNAMIC_LINK is used to test whether the executable was linked
dynamically or not. It's no less magic to define it in the linker
script than it is to define it in elf32-mips.c. In this case, I don't
see how to define it correctly in the linker script.
But, leaving that issue aside, we define this on all systems, in the
non-shared case, in _bfd_mips_elf_create_dynamic_sections. So, I
don't think we need to handle this symbol specially when we perform
relocations against it. Do you agree?
_bfd_mips_elf_create_dynamic_sections is not called in all cases: it
is not called when doing a static link. I believe that bit of code
got in there because some system expects _DYNAMIC_LINK to be defined
as 0 when doing a static link. I think we do need to handle this one
way or another.
Ian
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-08-03 9:29 ` Ian Lance Taylor
@ 1999-08-03 9:46 ` Mark Mitchell
1999-08-03 9:48 ` Mark Mitchell
1 sibling, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 1999-08-03 9:46 UTC (permalink / raw)
To: ian; +Cc: ralf, ralf, binutils, thockin, linux, linux-mips, linux-mips
Ian --
Thanks for the commentary. I'll address those issues later today.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: MIPS/ELF linker
1999-08-03 9:29 ` Ian Lance Taylor
1999-08-03 9:46 ` Mark Mitchell
@ 1999-08-03 9:48 ` Mark Mitchell
1 sibling, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 1999-08-03 9:48 UTC (permalink / raw)
To: ian; +Cc: ralf, ralf, binutils, thockin, linux, linux-mips, linux-mips
Ian> Since this symbol is in the reserved name space, it's OK for
Ian> the linker to define it magically. It's no more buggy for an
Ian> executable to use the symbol _DYNAMIC_LINK without a
Ian> definition than it is for an executable to use the symbol
Ian> __program_header_table without a definition.
That's true, from an ANSI C point of view. But, it's not true from a
system-specific point of view. Some systems have well-known entry
points beginnning with `_'. It seems unncessary to deal with this
_DYNAMIC_LINK trick on systems that don't need it; hence the
suggestion that the linker script is the place for it.
But, as you say, I'm not quite sure how to do that; I'll just restore
the original handling of this code.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~1999-08-03 9:48 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-07-31 14:49 MIPS/ELF linker Ralf Baechle
1999-07-31 15:26 ` Mark Mitchell
1999-07-31 16:23 ` Ralf Baechle
1999-07-31 16:41 ` Mark Mitchell
1999-07-31 16:46 ` Ralf Baechle
1999-08-01 14:01 ` Mark Mitchell
1999-08-03 9:29 ` Ian Lance Taylor
1999-08-03 9:46 ` Mark Mitchell
1999-08-03 9:48 ` Mark Mitchell
1999-08-01 14:03 ` Mark Mitchell
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).