[PATCH] Fix static linking for SH uClibc targets

Joe Seymour jseymour@codesourcery.com
Thu Mar 28 21:20:00 GMT 2013


This patch fixes a link error encountered when building static
executables that don't require stdio with a sh2-uclinux toolchain:

foo.c:
int
main (void)
{
  return 0;
}

> sh-uclinux-gcc -static foo.c
> /scratch/jseymour/sh-uclinux-lite/install/bin/../sh-uclinux/libc/usr/lib/libc.a(__uClibc_main.os): In function `*__GI___uClibc_init':
> /scratch/jseymour/sh-uclinux-lite/obj/uclibc-2011.03-999999-sh-uclinux-i686-pc-linux-gnu/default/libc/misc/internals/__uClibc_main.c:238: warning: relocation to "_stdio_init" references a different segment

The relocation was a R_SH_REL32 generated for a non-NULL test of
_stdio_init:
>    /*
>     * Initialize stdio here.  In the static library case, this will
>     * be bypassed if not needed because of the weak alias above.
>     * Thus we get a nice size savings because the stdio functions
>     * won't be pulled into the final static binary unless used.
>     */
>     if (likely(_stdio_init != NULL))
>         _stdio_init();

Elsewhere in elf32-sh.c warnings are suppressed for calls to undefined
weak functions, so it seems reasonable to do the same for their
corresponding non-NULL checks.

>        case R_SH_PLT32:
> #ifdef INCLUDE_SHMEDIA
>        case R_SH_PLT_LOW16:
>        case R_SH_PLT_MEDLOW16:
>        case R_SH_PLT_MEDHI16:
>        case R_SH_PLT_HI16:
> #endif
>          /* Relocation is to the entry for this symbol in the
>             procedure linkage table.  */
>
>          /* Resolve a PLT reloc against a local symbol directly,
>             without using the procedure linkage table.  */
>          if (h == NULL)
>            goto final_link_relocate;
>
>          /* We don't want to warn on calls to undefined weak symbols,
>             as calls to them must be protected by non-NULL tests
>             anyway, and unprotected calls would invoke undefined
>             behavior.  */
>          if (h->root.type == bfd_link_hash_undefweak)
>            check_segment[0] = check_segment[1] = -1;


With this patch I'm able to build and run static executables.

The ld binutils and gas testsuites shows no regressions, although
results for this target weren't clean to start with.

Note I wasn't able to build trunk uClibc with trunk binutils without
working around another SH issue. Time permitting I'll try and send a
patch for that too, but there's a good chance time wont be permitting :(

If this patch is OK could someone please commit it for me, I don't have
write access.

Thanks,

2013-03-XX  Joe Seymour  <jseymour@codesourcery.com>

	bfd/
	* elf32-sh.c (sh_elf_relocate_section): Suppress warnings for
	R_SH_REL32 relocations against undefined weak symbols.

diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index ba57caf..16f445e 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -4425,6 +4425,12 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
 	      check_segment[0] = check_segment[1] = -1;
 	    }
+	    /* We don't want warnings for non-NULL tests on undefined weak
+	       symbols.  */
+	    else if (r_type == R_SH_REL32
+		     && h
+		     && h->root.type == bfd_link_hash_undefweak) 
+	      check_segment[0] = check_segment[1] = -1;
 	  goto final_link_relocate;
 
 	case R_SH_GOTPLT32:



More information about the Binutils mailing list