From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark Mitchell To: ralf@uni-koblenz.de Cc: ralf@gnu.org, binutils@sourceware.cygnus.com, thockin@cobaltnet.com, linux@engr.sgi.com, linux-mips@fnet.fr, linux-mips@vger.rutgers.edu Subject: Re: MIPS/ELF linker Date: Sun, 01 Aug 1999 14:01:00 -0000 Message-id: <19990801140327R.mitchell@codesourcery.com> References: <19990731233150.Q12249@uni-koblenz.de> <19990731152842N.mitchell@codesourcery.com> <19990801012203.U12249@uni-koblenz.de> X-SW-Source: 1999-08/msg00000.html 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 * 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