Bug 20308 - Gold should support i386 TLS code sequences without PLT
Summary: Gold should support i386 TLS code sequences without PLT
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.27
: P2 normal
Target Milestone: 2.27
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-06-28 15:02 UTC by H.J. Lu
Modified: 2016-08-18 16:24 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
object files that then failed the test (1.68 KB, application/gzip)
2016-08-17 11:25 UTC, ncahill_alt
Details
Try this (1.13 KB, patch)
2016-08-17 14:50 UTC, H.J. Lu
Details | Diff
result of changes (1.67 KB, application/gzip)
2016-08-17 16:16 UTC, ncahill_alt
Details

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2016-06-28 15:02:51 UTC
We can generate i386 TLS code sequences for general and local dynamic
models without PLT, which uses indirect call via GOT:

call *___tls_get_addr@GOT(%reg)

where EBX register isn't required as GOT base, instead of direct call:

call ___tls_get_addr[@PLT]

which requires EBX register as GOT base.

Since direct call is 4-byte long and indirect call, is 5-byte long, the
extra one byte must be handled properly.

For general dynamic model, 7-byte lea instruction before call instruction
is replaced by 6-byte one to make room for indirect call.  For local
dynamic model, we simply use 5-byte indirect call.

TLS linker optimization is updated to recognize new instruction patterns.
For local dynamic model to local exec model transition, we generate
a 6-byte lea instruction as nop, instead of a 1-byte nop plus a 4-byte
lea instruction.  See:

https://groups.google.com/forum/#!topic/ia32-abi/1j0R7rPz_GE
Comment 1 H.J. Lu 2016-06-29 13:49:21 UTC
A patch is posted at

https://sourceware.org/ml/binutils/2016-06/msg00500.html
Comment 2 Sourceware Commits 2016-06-29 15:39:59 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=b287eca391bbb10e709fb8ba9a56be166ab2ff1d

commit b287eca391bbb10e709fb8ba9a56be166ab2ff1d
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jun 29 08:38:43 2016 -0700

    gold: Support 386 TLS code sequences without PLT
    
    There are extensions to 386 psABI:
    
    https://groups.google.com/forum/#!topic/ia32-abi/awsRSvJOJfs
    
    to call tls_get_addr via GOT:
    
    call *___tls_get_addr@GOT(%reg)
    
    where EBX register isn't required as GOT base.
    
    Since direct call is 4-byte long and indirect call, is 5-byte long, the
    extra one byte must be handled properly.
    
    For general dynamic model, 7-byte lea instruction before call
    instruction is replaced by 6-byte one to make room for indirect call.
    For local dynamic model, we simply use 5-byte indirect call.
    
    TLS linker optimization is updated to recognize new instruction
    patterns.  For local dynamic model to local exec model transition,
    we generate a 6-byte lea instruction as nop, instead of a 1-byte nop
    plus a 4-byte lea instruction.
    
    	PR gold/20308
    	* i386.cc (Target_i386::Relocate::relocate): Allow
    	R_386_GOT32X relocation against ___tls_get_addr.
    	(Target_i386::Relocate::tls_gd_to_ie): Support indirect
    	call to __tls_get_addr.
    	(Target_i386::Relocate::tls_gd_to_le): Likewise.
    	(Target_i386::Relocate::tls_ld_to_le): Likewise.
    	* testsuite/Makefile.am (check_PROGRAMS): Add pr20308a_test,
    	pr20308b_test, pr20308c_test, pr20308d_test, pr20308e_test.
    	(pr20308a_test_SOURCES): New.
    	(pr20308a_test_DEPENDENCIES): Likewise.
    	(pr20308a_test_CFLAGS): Likewise.
    	(pr20308a_test_LDFLAGS): Likewise.
    	(pr20308a_test_LDADD): Likewise.
    	(pr20308b_test_SOURCES): Likewise.
    	(pr20308b_test_DEPENDENCIES): Likewise.
    	(pr20308b_test_CFLAGS): Likewise.
    	(pr20308b_test_LDFLAGS): Likewise.
    	(pr20308b_test_LDADD): Likewise.
    	(pr20308c_test_SOURCES): Likewise.
    	(pr20308c_test_DEPENDENCIES): Likewise.
    	(pr20308c_test_CFLAGS): Likewise.
    	(pr20308c_test_LDFLAGS): Likewise.
    	(pr20308c_test_LDADD): Likewise.
    	(pr20308d_test_SOURCES): Likewise.
    	(pr20308d_test_DEPENDENCIES): Likewise.
    	(pr20308d_test_CFLAGS): Likewise.
    	(pr20308d_test_LDFLAGS): Likewise.
    	(pr20308d_test_LDADD): Likewise.
    	(pr20308e_test_SOURCES): Likewise.
    	(pr20308e_test_DEPENDENCIES): Likewise.
    	(pr20308e_test_CFLAGS): Likewise.
    	(pr20308e_test_LDFLAGS): Likewise.
    	(pr20308e_test_LDADD): Likewise.
    	(pr20308a.so): Likewise.
    	(pr20308b.so): Likewise.
    	(pr20308_gd.o): Likewise.
    	(pr20308_ld.o): Likewise.
    	(MOSTLYCLEANFILES): Add pr20308a.so pr20308b.so.
    	* testsuite/Makefile.in: Regenerated.
    	* testsuite/pr20308_def.c: New file.
    	* testsuite/pr20308_gd.S: Likewise.
    	* testsuite/pr20308_ld.S: Likewise.
    	* testsuite/pr20308_main.c: Likewise.
Comment 3 H.J. Lu 2016-06-29 15:43:15 UTC
Fixed for 2.27.
Comment 4 ncahill_alt 2016-08-17 11:25:04 UTC
Created attachment 9443 [details]
object files that then failed the test
Comment 5 ncahill_alt 2016-08-17 11:26:12 UTC
Regarding this update, I'm getting a failure on "make testsuite/pr20308a_test":

pr20308_gd.o:function test_gd: error: missing expected TLS relocation
gcctestdir/ld: error: missing expected TLS relocation
pr20308_ld.o:function test_ld: error: missing expected TLS relocation
pr20308_ld.o:function test_ld: error: missing expected TLS relocation
gcctestdir/ld: error: missing expected TLS relocation

I see this message twice in i386.cc:

------ line 634 ----------
    ~Relocate()
    {
      if (this->skip_call_tls_get_addr_)
	{
	  // FIXME: This needs to specify the location somehow.
	  gold_error(_("missing expected TLS relocation"));
	}
    }

------ line 2787 -----------
  const elfcpp::Rel<32, false> rel(preloc);
  unsigned int r_type = elfcpp::elf_r_type<32>(rel.get_r_info());

  if (this->skip_call_tls_get_addr_)
    {
      if ((r_type != elfcpp::R_386_PLT32
	   && r_type != elfcpp::R_386_GOT32X
	   && r_type != elfcpp::R_386_PC32)
	  || gsym == NULL
	  || strcmp(gsym->name(), "___tls_get_addr") != 0)
	gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			       _("missing expected TLS relocation"));
      else
	{
	  this->skip_call_tls_get_addr_ = false;
	  return false;
	}
    }
---------------

One thing I notice is this:

00000066 R_386_GOT32       ___tls_get_addr

Hopefully that's the problem.  Also I wonder if it would be helpful to make those two error messages slightly different so one could pick out which is which.

Thank you.
Neil.
Comment 6 H.J. Lu 2016-08-17 14:50:59 UTC
Created attachment 9444 [details]
Try this
Comment 7 ncahill_alt 2016-08-17 16:16:20 UTC
Created attachment 9445 [details]
result of changes

It still fails:

pr20308_gd.o:function test_gd: error: missing expected TLS relocation
pr20308_ld.o:function test_ld: error: missing expected TLS relocation
Comment 8 H.J. Lu 2016-08-17 16:25:13 UTC
(In reply to ncahill_alt from comment #7)
> Created attachment 9445 [details]
> result of changes
> 
> It still fails:
> 
> pr20308_gd.o:function test_gd: error: missing expected TLS relocation
> pr20308_ld.o:function test_ld: error: missing expected TLS relocation

Please show the output of "readelf -r pr20308_gd.o"
Comment 9 ncahill_alt 2016-08-17 17:21:11 UTC
Relocation section '.rel.text' at offset 0x2ec contains 12 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000002  00000b02 R_386_PC32        00000000   __x86.get_pc_thunk.bx
00000008  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
00000012  00000d12 R_386_TLS_GD      00000000   gd
00000017  00000e04 R_386_PLT32       00000000   ___tls_get_addr
00000022  00000b02 R_386_PC32        00000000   __x86.get_pc_thunk.bx
00000028  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
00000031  00000d12 R_386_TLS_GD      00000000   gd
00000036  00000e04 R_386_PLT32       00000000   ___tls_get_addr
00000051  00001102 R_386_PC32        00000000   __x86.get_pc_thunk.cx
00000057  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
00000060  00000d12 R_386_TLS_GD      00000000   gd
00000066  00000e03 R_386_GOT32       00000000   ___tls_get_addr

CFLAGS = -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops
CXXFLAGS = -g -O2
LDFLAGS = -Wl,-O1

GCC is 5.2.0, i686-pc-linux-gnu-gcc
Comment 10 H.J. Lu 2016-08-17 17:29:49 UTC
(In reply to ncahill_alt from comment #9)
> Relocation section '.rel.text' at offset 0x2ec contains 12 entries:
>  Offset     Info    Type            Sym.Value  Sym. Name
> 00000002  00000b02 R_386_PC32        00000000   __x86.get_pc_thunk.bx
> 00000008  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
> 00000012  00000d12 R_386_TLS_GD      00000000   gd
> 00000017  00000e04 R_386_PLT32       00000000   ___tls_get_addr
> 00000022  00000b02 R_386_PC32        00000000   __x86.get_pc_thunk.bx
> 00000028  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
> 00000031  00000d12 R_386_TLS_GD      00000000   gd
> 00000036  00000e04 R_386_PLT32       00000000   ___tls_get_addr
> 00000051  00001102 R_386_PC32        00000000   __x86.get_pc_thunk.cx
> 00000057  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
> 00000060  00000d12 R_386_TLS_GD      00000000   gd
> 00000066  00000e03 R_386_GOT32       00000000   ___tls_get_addr
> 
> CFLAGS = -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe
> -funroll-loops -funswitch-loops
> CXXFLAGS = -g -O2
> LDFLAGS = -Wl,-O1
> 
> GCC is 5.2.0, i686-pc-linux-gnu-gcc

Please show the command line used to compile pr20308_gd.o.

BTW, did you run "make clean" first?
Comment 11 Cary Coutant 2016-08-17 17:42:38 UTC
> Please show the command line used to compile pr20308_gd.o.
>
> BTW, did you run "make clean" first?

Yeah, the build rules should also have a dependency on gcctestdir/as.
Forgot that when fixing the x86_64 test, sorry.

-cary
Comment 12 ncahill_alt 2016-08-17 18:07:18 UTC
(In reply to H.J. Lu from comment #10)
> (In reply to ncahill_alt from comment #9)
> > Relocation section '.rel.text' at offset 0x2ec contains 12 entries:
> >  Offset     Info    Type            Sym.Value  Sym. Name
> > 00000002  00000b02 R_386_PC32        00000000   __x86.get_pc_thunk.bx
> > 00000008  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
> > 00000012  00000d12 R_386_TLS_GD      00000000   gd
> > 00000017  00000e04 R_386_PLT32       00000000   ___tls_get_addr
> > 00000022  00000b02 R_386_PC32        00000000   __x86.get_pc_thunk.bx
> > 00000028  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
> > 00000031  00000d12 R_386_TLS_GD      00000000   gd
> > 00000036  00000e04 R_386_PLT32       00000000   ___tls_get_addr
> > 00000051  00001102 R_386_PC32        00000000   __x86.get_pc_thunk.cx
> > 00000057  00000c0a R_386_GOTPC       00000000   _GLOBAL_OFFSET_TABLE_
> > 00000060  00000d12 R_386_TLS_GD      00000000   gd
> > 00000066  00000e03 R_386_GOT32       00000000   ___tls_get_addr
> > 
> > CFLAGS = -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe
> > -funroll-loops -funswitch-loops
> > CXXFLAGS = -g -O2
> > LDFLAGS = -Wl,-O1
> > 
> > GCC is 5.2.0, i686-pc-linux-gnu-gcc
> 
> Please show the command line used to compile pr20308_gd.o.

i686-pc-linux-gnu-gcc -Bgcctestdir/ -fPIE -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops -Bgcctestdir/ -Wl,-R,. -Wl,-O1 -o pr20308a_test pr20308a_test-pr20308_main.o pr20308a_test-pr20308_def.o pr20308_gd.o pr20308_ld.o -ldl

> 
> BTW, did you run "make clean" first?

Yes, I built binutils from scratch each time.  This all looks odd but basically...
1.  CFLAGS is very well tested, I won't go into it but it gives helpful profiling results, for example I was able to report performance issues with GCC.
2.  CXXFLAGS should have been the same, I had a script that set everything but I had to recreate it and forgot to set CXXFLAGS.
Comment 13 ncahill_alt 2016-08-17 18:26:26 UTC
Oh sorry, here it is:

`echo i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I../../../binutils-2.27/gold/testsuite -I..  -I../../../binutils-2.27/gold/testsuite -I../../../binutils-2.27/gold/testsuite/.. -I../../../binutils-2.27/gold/testsuite/../../include -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. -DLOCALEDIR="\"/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale\""   -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops | sed -e 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'` -Bgcctestdir/ -c -o pr20308_gd.o ../../../binutils-2.27/gold/testsuite/pr20308_gd.S

which translates to

i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I../../../binutils-2.27/gold/testsuite -I.. -I../../../binutils-2.27/gold/testsuite -I../../../binutils-2.27/gold/testsuite/.. -I../../../binutils-2.27/gold/testsuite/../../include -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I.. -DLOCALEDIR="/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale" -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops -funswitch-loops -Bgcctestdir/ -c -o pr20308_gd.o ../../../binutils-2.27/gold/testsuite/pr20308_gd.S
Comment 14 H.J. Lu 2016-08-17 23:50:59 UTC
(In reply to ncahill_alt from comment #13)
> Oh sorry, here it is:
> 
> `echo i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I.
> -I../../../binutils-2.27/gold/testsuite -I.. 
> -I../../../binutils-2.27/gold/testsuite
> -I../../../binutils-2.27/gold/testsuite/..
> -I../../../binutils-2.27/gold/testsuite/../../include
> -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I..
> -DLOCALEDIR="\"/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale\""  
> -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow
> -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
> -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2
> -fno-inline -pipe -funroll-loops -funswitch-loops | sed -e
> 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'` -Bgcctestdir/ -c -o pr20308_gd.o
> ../../../binutils-2.27/gold/testsuite/pr20308_gd.S
> 
> which translates to
> 
> i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I.
> -I../../../binutils-2.27/gold/testsuite -I..
> -I../../../binutils-2.27/gold/testsuite
> -I../../../binutils-2.27/gold/testsuite/..
> -I../../../binutils-2.27/gold/testsuite/../../include
> -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I..
> -DLOCALEDIR="/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale" -W
> -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144
> -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2
> -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops
> -funswitch-loops -Bgcctestdir/ -c -o pr20308_gd.o
> ../../../binutils-2.27/gold/testsuite/pr20308_gd.S

This should generate R_386_GOT32X, not R_386_GOT32 relocation.
Comment 15 ncahill_alt 2016-08-18 06:52:48 UTC
(In reply to H.J. Lu from comment #14)
> (In reply to ncahill_alt from comment #13)
> > Oh sorry, here it is:
> > 
> > `echo i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I.
> > -I../../../binutils-2.27/gold/testsuite -I.. 
> > -I../../../binutils-2.27/gold/testsuite
> > -I../../../binutils-2.27/gold/testsuite/..
> > -I../../../binutils-2.27/gold/testsuite/../../include
> > -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I..
> > -DLOCALEDIR="\"/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale\""  
> > -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow
> > -Wstack-usage=262144 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
> > -fmerge-constants -O2 -fno-tree-slsr -march=athlon64 -mtune=core2
> > -fno-inline -pipe -funroll-loops -funswitch-loops | sed -e
> > 's/-Wp,-D_FORTIFY_SOURCE=[0-9[0-9]]*//'` -Bgcctestdir/ -c -o pr20308_gd.o
> > ../../../binutils-2.27/gold/testsuite/pr20308_gd.S
> > 
> > which translates to
> > 
> > i686-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I.
> > -I../../../binutils-2.27/gold/testsuite -I..
> > -I../../../binutils-2.27/gold/testsuite
> > -I../../../binutils-2.27/gold/testsuite/..
> > -I../../../binutils-2.27/gold/testsuite/../../include
> > -I../../../binutils-2.27/gold/testsuite/../../elfcpp -I..
> > -DLOCALEDIR="/usr/share/binutils-data/i686-pc-linux-gnu/2.27/locale" -W
> > -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144
> > -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fmerge-constants -O2
> > -fno-tree-slsr -march=athlon64 -mtune=core2 -fno-inline -pipe -funroll-loops
> > -funswitch-loops -Bgcctestdir/ -c -o pr20308_gd.o
> > ../../../binutils-2.27/gold/testsuite/pr20308_gd.S
> 
> This should generate R_386_GOT32X, not R_386_GOT32 relocation.

Could this be a glibc problem?  I see this patch dated December 2015:

> diff --git a/backends/ChangeLog b/backends/ChangeLog 
> index 4b604fd..cc0dd6f 100644 
> --- a/backends/ChangeLog 
> +++ b/backends/ChangeLog 
> @@ -1,3 +1,8 @@ 
> +2015-12-28 Mark Wielaard <mjw(a)redhat.com>; 
> + 
> + * i386_reloc.def: Add GOT32X. 
> + * x86_64_reloc.def: Add GOTPCRELX and REX_GOTPCRELX. 
> + 2015-12-08 Jose E. Marchesi <jose.marchesi(a)oracle.com>;

I'm using glibc-2.22 from 2015-08-14.  In fact, I can confirm that elf.h defines R_386_GOT32 but not R_386_GOT32X:

> #define R_68K_GOT32     7               /* 32 bit PC relative GOT entry */
> #define R_68K_GOT32O    10              /* 32 bit GOT offset */
> #define R_386_GOT32        3            /* 32 bit GOT entry */
> #define R_ARM_GOT32             26      /* 32 bit GOT entry */
> #define R_SH_GOT32              160
> #define R_390_GOT32             7       /* 32 bit GOT offset.  */
> #define R_X86_64_GOT32          3       /* 32 bit GOT entry */
> #define R_MN10300_GOT32         17      /* 32-bit offset to GOT entry.  */

I think this must be it.
Comment 16 ncahill_alt 2016-08-18 13:44:46 UTC
I've tried this again:

1.  I build binutils-2.27 in an empty folder.
2.  I run "make check" in "binutils-2.27/gold/"
3.  It fails with "missing expected TLS relocation".  
"readelf -r pr20308_gd.o" shows R_386_GOT32.

4.  I run "make clean" in "binutils-2.27/gold/testsuite/".
5.  I run "make check" in "binutils-2.27/gold/".
6.  All tests pass and readelf shows "unrecognized: 2b".

This is with the changes above in the "try this" attachment.  I also tried without them, the error is not resolved.
Comment 17 H.J. Lu 2016-08-18 14:56:27 UTC
(In reply to ncahill_alt from comment #16)
> I've tried this again:
> 
> 1.  I build binutils-2.27 in an empty folder.
> 2.  I run "make check" in "binutils-2.27/gold/"
> 3.  It fails with "missing expected TLS relocation".  
> "readelf -r pr20308_gd.o" shows R_386_GOT32.
> 
> 4.  I run "make clean" in "binutils-2.27/gold/testsuite/".
> 5.  I run "make check" in "binutils-2.27/gold/".
> 6.  All tests pass and readelf shows "unrecognized: 2b".
> 
> This is with the changes above in the "try this" attachment.  I also tried
> without them, the error is not resolved.

You need to find out why #3 fails and #6 passes.
Comment 18 ncahill_alt 2016-08-18 16:24:19 UTC
diff -ur a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
--- a/gold/testsuite/Makefile.am	2016-08-18 17:00:09.969119174 +0000
+++ b/gold/testsuite/Makefile.am	2016-08-18 17:09:28.772423751 +0000
@@ -1297,10 +1297,10 @@
 pr20308b.so: pr20308_def.o gcctestdir/ld
 	$(LINK) -Bgcctestdir/ -shared pr20308_def.o
 
-pr20308_gd.o: pr20308_gd.S
+pr20308_gd.o: pr20308_gd.S gcctestdir/as
 	$(COMPILE) -Bgcctestdir/ -c -o $@ $<
 
-pr20308_ld.o: pr20308_ld.S
+pr20308_ld.o: pr20308_ld.S gcctestdir/as
 	$(COMPILE) -Bgcctestdir/ -c -o $@ $<
 
 endif DEFAULT_TARGET_I386