This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] ld: Correct private data merging for DSOs


Hi,

 We have an issue in the linker with merging private data where dynamic 
shared objects are involved.  For MIPS targets it affects file header flag 
and file attribute ABI compatibility tests that in most, though not all 
cases are not made for such objects.  Other targets might be affected too; 
I encourage the respective maintainters to double-check their code.

 There are a few conditions involved, let's examine them one by one, by 
input object type and some of its properties:

1. Relocatable object, non-empty input sections present.  Such objects are 
   checked for compatibility with other objects involved in the link.  The 
   condition is bfd_count_sections on the input BFD in lang_check.  The 
   sections are further checked in _bfd_mips_elf_merge_private_bfd_data to 
   have some contents (with some restrictions) -- this additional check is
   only made for file header flags, however for attributes to have any 
   significant meaning a non-empty .gnu.attributes section must have been 
   created, so the check would have been redundant.  There is no issue for 
   such objects.

2. Relocatable object, only empty input sections present.  These objects 
   pass the bfd_count_sections check in lang_check and are processed by 
   _bfd_mips_elf_merge_private_bfd_data.  As noted above this implies no 
   attributes and then for file header flag compatibility tests a 
   non-empty section would have to be present.  In theory one could be 
   present if created by the linker rather than obtained from input.  In 
   practice I think it does not happen; in particular I believe the 
   creation of the dynamic sections can never be triggered in the linker 
   by an input file that only has empty input sections.

3. Relocatable object, no input sections present.  These objects are 
   excluded by the bfd_count_sections condition in lang_check.  Like with 
   files that only have empty input sections, I believe no linker-created
   sections can be added.

4. Dynamic shared object, non-empty input sections present.  Such objects 
   are supposed to be checked for compatibility with other objects 
   involved in the link (there's explicit code in 
   _bfd_mips_elf_merge_private_bfd_data to handle DSOs and besides I 
   think we should treat them consistently with relocatable objects).  
   However for DSOs the section count is reset to zero in 
   elf_link_add_object_symbols.

   Now if this is the first object seen in the link that implies dynamic 
   sections, they are later on created by the linker and the section count 
   is increased again.  As a result the DSO passes the bfd_count_sections 
   condition in lang_check and is let through to 
   _bfd_mips_elf_merge_private_bfd_data.  This lets attributes be 
   verified.  The ELF file header compatibility check is made too as the
   dynamic sections created will have some contents, although I don't 
   think they are relevant for ABI compatibility checks.

   If dynamic sections have already been created then the DSO is silently 
   skipped and ABI compatibility checks are not made.

5. Dynamic shared object, only empty or no sections present.  In both 
   cases the section count is set to zero in elf_link_add_object_symbols, 
   however if such a DSO triggered the creation of dynamic sections, then 
   it will trigger the ABI compatibility checks in 
   _bfd_mips_elf_merge_private_bfd_data.  Of course that affects file 
   header flags only as attributes by definition will be absent.

 Interestingly enough when the GCC driver is used to link an ordinary 
dynamic executable on the MIPS/Linux target (i.e. no special options are 
used such as -nostdlib), not even the first DSO is checked for ABI 
compatibility as crti.o is always earlier on and will have triggered the 
creation of dynamic sections already.

 To address these issues I examined a few possible solutions.  At first I 
was tempted to discard the removal of the old state from 
elf_link_add_object_symbols, referred to as "hack" there, and use a flag 
as suggested there for a more proper approach, but that has turned out 
rather infeasible.  Places that interpret the section state are scattered 
throughout BFD, including many backends and also non-ELF code.  Auditing 
all of them at this stage would involve a lot of effort, and cause a risk 
of subtle breakage in many places, especially as I can't say I'm confident 
all these places would trigger regressions in our test suite.  This may 
well have been the original reason for this "hack" too.

 Therefore I have decided to keep the current approach and look for a 
simpler way instead.  I thought that before the section state is cleared 
in elf_link_add_object_symbols, a copy could be made for places that might 
be interested later on in actual input sections only.  This turned out to 
work quite well and only required a further update to lang_check and 
_bfd_mips_elf_merge_private_bfd_data.  However eventually I realised this 
would be several changes and extra state just to address the case of empty 
DSOs, which in reality firstly should not happen in the first place, and 
secondly even if they did, then they would generally be examined for file 
header flag compatibility by the dynamic linker at the run time regardless 
of their lack of actual contents.

 Therefore I have finally come up with this simplest solution where all 
DSOs are examined unconditionally, which became a one-line change to 
generic code in lang_check, and then a further update to 
_bfd_mips_elf_merge_private_bfd_data so that empty DSOs (of which there 
would be all, due to the hack in elf_link_add_object_symbols) are not 
excluded.

 Beyond the compatibility checks I have also considered what the effect 
might be of the actual attribute merges now, with DSOs in the picture.  I 
think about the only effect it will have would be a configuration where 
executable with no FP ABI specified linked with incompatible shared 
libraries, say a hard-float and a soft-float one.  Of course such an 
executable would be compatible with both and having no FP ABI set would 
not pass any FP data around, i.e. the two incompatible FP ABIs would 
remain contained to the respective shared libraries.  However the first 
DSO spotted with an FP ABI set would pass it on to the executable, which 
would then reject the other DSO.

 I am not sure if such a configuration matters in reality -- if you think 
it does, then I'll be happy to consider it in a follow-on patch, however 
at this point I suspect it does not.  And it is also tricky in practice as 
a later relocatable object might indeed have a specific FP ABI set causing 
a DSO already accepted incompatible.

 In addition to the change described above I made I have decided to 
exclude linker-created sections in _bfd_mips_elf_merge_private_bfd_data 
explicitly too.  Although this probably serves documentation purposes only 
as such sections will not have been created for DSOs by the time the input 
section state is copied, and as noted above, for relocatable objects (such 
as crti.o), other sections will contain data too.

 The functionality considered here was not covered by the testsuite, 
however the new test cases included here cause the following failures with 
our current code as is:

FAIL: MIPS double-float executable with single-float library 3 (o32)
FAIL: MIPS double-float executable with single-float library 4 (o32)
FAIL: MIPS single-float executable with double-float library 3 (o32)
FAIL: MIPS single-float executable with double-float library 4 (o32)
FAIL: MIPS double-float executable with single-float library 3 (n32)
FAIL: MIPS double-float executable with single-float library 4 (n32)
FAIL: MIPS single-float executable with double-float library 3 (n32)
FAIL: MIPS single-float executable with double-float library 4 (n32)
FAIL: MIPS double-float executable with single-float library 3 (n64)
FAIL: MIPS double-float executable with single-float library 4 (n64)
FAIL: MIPS single-float executable with double-float library 3 (n64)
FAIL: MIPS single-float executable with double-float library 4 (n64)
FAIL: MIPS abicalls interlinking non-PIC executable 1 (o32)
FAIL: MIPS abicalls interlinking non-PIC executable 2 (o32)
FAIL: MIPS abicalls interlinking non-PIC executable 1 (n32)
FAIL: MIPS abicalls interlinking non-PIC executable 2 (n32)
FAIL: MIPS abicalls interlinking non-PIC executable 1 (n64)
FAIL: MIPS abicalls interlinking non-PIC executable 2 (n64)

-- that are removed once the fix has been applied.  These show how the 
order of DSOs matters, the remaining added tests succeed regardless, 
providing coverage for the respective execution paths.

 A few existing cases had to be adjusted though, as they failed to 
complain where non-abicalls relocatables were linked with a DSO -- this 
case is commented on in _bfd_mips_elf_merge_private_bfd_data: "DSOs should 
only be linked with CPIC code," so I believe that the new complaint is 
right and the existing test cases wrong.

 I have regression-tested this change over the usual 136 targets with no 
problems spotted.  Any questions or comments; or otherwise OK to apply?

2012-12-01  Maciej W. Rozycki  <macro@codesourcery.com>

	bfd/
	* elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Always
	do file header flag compatibility checks on dynamic shared
	objects.  Ignore linker-created sections when qualifying
	relocatable objects for these checks.

	ld/
	* ldlang.c (lang_check): Always merge private BFD data of
	dynamic shared objects.

	ld/testsuite/
	* ld-elf/elf.exp: Add -KPIC to ASFLAGS for mips*-*-* and the
	pr14170 test.
	* ld-elf/export-class.exp: Add -KPIC to ASFLAGS for mips*-*-*.
	* ld-mips-elf/export-class.exp (mips_export_class_test): Add
	-KPIC to AFLAGS.
	* ld-mips-elf/abicalls-lib.s: New test source.
	* ld-mips-elf/abicalls.s: New test source.
	* ld-mips-elf/abicalls.ll: New test.
	* ld-mips-elf/attr-gnu-4-1.gd: New test.
	* ld-mips-elf/attr-gnu-4-12.ll: New test.
	* ld-mips-elf/attr-gnu-4-2.gd: New test.
	* ld-mips-elf/attr-gnu-4-21.ll: New test.
	* ld-mips-elf/mips-elf.exp: Run the new tests.

  Maciej

binutils-merge-private-sections.diff
Index: binutils-fsf-trunk-quilt/bfd/elfxx-mips.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/bfd/elfxx-mips.c	2012-12-01 11:40:50.000000000 +0000
+++ binutils-fsf-trunk-quilt/bfd/elfxx-mips.c	2012-12-01 12:19:13.341820501 +0000
@@ -13985,7 +13985,6 @@ _bfd_mips_elf_merge_private_bfd_data (bf
   flagword old_flags;
   flagword new_flags;
   bfd_boolean ok;
-  bfd_boolean null_input_bfd = TRUE;
   asection *sec;
 
   /* Check if we have the same endianness.  */
@@ -14057,29 +14056,34 @@ _bfd_mips_elf_merge_private_bfd_data (bf
   if (new_flags == old_flags)
     return TRUE;
 
-  /* Check to see if the input BFD actually contains any sections.
-     If not, its flags may not have been initialised either, but it cannot
-     actually cause any incompatibility.  */
-  for (sec = ibfd->sections; sec != NULL; sec = sec->next)
+  /* For relocatable objects check to see if the input BFD actually contains
+     any sections.  If not, its flags may not have been initialised either,
+     but it cannot actually cause any incompatibility.  */
+  if (!(ibfd->flags & DYNAMIC))
     {
-      /* Ignore synthetic sections and empty .text, .data and .bss sections
-	 which are automatically generated by gas.  Also ignore fake
-	 (s)common sections, since merely defining a common symbol does
-	 not affect compatibility.  */
-      if ((sec->flags & SEC_IS_COMMON) == 0
-	  && strcmp (sec->name, ".reginfo")
-	  && strcmp (sec->name, ".mdebug")
-	  && (sec->size != 0
-	      || (strcmp (sec->name, ".text")
-		  && strcmp (sec->name, ".data")
-		  && strcmp (sec->name, ".bss"))))
+      bfd_boolean null_input_bfd = TRUE;
+
+      for (sec = ibfd->sections; sec != NULL; sec = sec->next)
 	{
-	  null_input_bfd = FALSE;
-	  break;
+	  /* Ignore synthetic sections and empty .text, .data and .bss
+	     sections which are automatically generated by gas.  Also ignore
+	     fake (s)common sections, since merely defining a common symbol
+	     does not affect compatibility.  */
+	  if ((sec->flags & (SEC_LINKER_CREATED | SEC_IS_COMMON)) == 0
+	      && strcmp (sec->name, ".reginfo")
+	      && strcmp (sec->name, ".mdebug")
+	      && (sec->size != 0
+		  || (strcmp (sec->name, ".text")
+		      && strcmp (sec->name, ".data")
+		      && strcmp (sec->name, ".bss"))))
+	    {
+	      null_input_bfd = FALSE;
+	      break;
+	    }
 	}
+      if (null_input_bfd)
+	return TRUE;
     }
-  if (null_input_bfd)
-    return TRUE;
 
   ok = TRUE;
 
Index: binutils-fsf-trunk-quilt/ld/ldlang.c
===================================================================
--- binutils-fsf-trunk-quilt.orig/ld/ldlang.c	2012-12-01 11:40:50.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/ldlang.c	2012-12-01 11:46:48.560697029 +0000
@@ -5930,10 +5930,13 @@ lang_check (void)
 		   bfd_printable_name (input_bfd), input_bfd,
 		   bfd_printable_name (link_info.output_bfd));
 	}
-      else if (bfd_count_sections (input_bfd))
+      else if (bfd_count_sections (input_bfd) || (input_bfd->flags & DYNAMIC))
 	{
 	  /* If the input bfd has no contents, it shouldn't set the
-	     private data of the output bfd.  */
+	     private data of the output bfd.  Dynamic objects are always
+	     checked as this is what the dynamic linker will generally
+	     do too at the run time.  The backend still has a choice to
+	     skip some checks in that case.  */
 
 	  bfd_error_handler_type pfn = NULL;
 
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-elf/elf.exp
===================================================================
--- binutils-fsf-trunk-quilt.orig/ld/testsuite/ld-elf/elf.exp	2012-12-01 11:40:50.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-elf/elf.exp	2012-12-01 11:42:04.341781075 +0000
@@ -64,6 +64,10 @@ if { ![istarget hppa64*-hpux*] } {
     }
 
     if { [check_shared_lib_support] } then {
+	set old_asflags $ASFLAGS
+	if { [istarget mips*-*-*] } {
+	    append ASFLAGS " -KPIC"
+	}
 	run_ld_link_tests {
 	    {"Build pr14170a.o" "" "" "pr14170a.s" {} "pr14170.a" }
 	}
@@ -75,6 +79,7 @@ if { ![istarget hppa64*-hpux*] } {
 		"tmpdir/pr14170a.o tmpdir/pr14170.so" "" "pr14170c.s"
 		{ } "pr14170" }
 	}
+	set ASFLAGS $old_asflags
     }
 }
 
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-elf/export-class.exp
===================================================================
--- binutils-fsf-trunk-quilt.orig/ld/testsuite/ld-elf/export-class.exp	2012-12-01 11:40:50.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-elf/export-class.exp	2012-12-01 11:42:04.341781075 +0000
@@ -39,6 +39,11 @@ if { ![istarget *-*-linux*]
 
 set testname "Symbol export class test"
 
+set old_asflags $ASFLAGS
+if { [istarget mips*-*-*] } {
+    append ASFLAGS " -KPIC"
+}
+
 # Build an auxiliary shared object with conflicting versioned symbol
 # definitions.
 run_ld_link_tests [list \
@@ -85,3 +90,5 @@ run_ld_link_tests [list \
 	"export-class.so" \
     ] \
 ]
+
+set ASFLAGS $old_asflags
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/abicalls-lib.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/abicalls-lib.s	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1,6 @@
+	.data
+	.globl	bar
+	.type	bar, @object
+bar:
+	.word	0
+	.size	bar, . - bar
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/abicalls.ll
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/abicalls.ll	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1 @@
+.*: .*: warning: linking abicalls files with non-abicalls files
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/abicalls.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/abicalls.s	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1,6 @@
+	.data
+	.globl	foo
+	.type	foo, @object
+foo:
+	.dc.a	bar
+	.size	foo, . - foo
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-1.gd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-1.gd	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1,4 @@
+Attribute Section: gnu
+File Attributes
+  Tag_GNU_MIPS_ABI_FP: Hard float \(double precision\)
+#pass
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-12.ll
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-12.ll	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1 @@
+.*: .* uses -mdouble-float \(set by .*\.o\), .*\.so uses -msingle-float
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-2.gd
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-2.gd	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1,4 @@
+Attribute Section: gnu
+File Attributes
+  Tag_GNU_MIPS_ABI_FP: Hard float \(single precision\)
+#pass
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-21.ll
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/attr-gnu-4-21.ll	2012-12-01 11:42:04.341781075 +0000
@@ -0,0 +1 @@
+.*: .* uses -msingle-float \(set by .*\.o\), .*\.so uses -mdouble-float
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/export-class.exp
===================================================================
--- binutils-fsf-trunk-quilt.orig/ld/testsuite/ld-mips-elf/export-class.exp	2012-12-01 11:40:50.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/export-class.exp	2012-12-01 11:42:04.341781075 +0000
@@ -36,7 +36,7 @@ proc mips_export_class_test { abi flag e
 
     set dump [string map {o32 32 n32 32 n64 64} $abi]
 
-    set AFLAGS "$flag -EB"
+    set AFLAGS "$flag -EB -KPIC"
     set LDFLAGS "-m$emul"
 
     # Build an auxiliary shared object with conflicting versioned symbol
Index: binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
--- binutils-fsf-trunk-quilt.orig/ld/testsuite/ld-mips-elf/mips-elf.exp	2012-12-01 11:40:50.000000000 +0000
+++ binutils-fsf-trunk-quilt/ld/testsuite/ld-mips-elf/mips-elf.exp	2012-12-01 11:42:04.361764845 +0000
@@ -626,6 +626,175 @@ run_dump_test "attr-gnu-4-44"
 run_dump_test "attr-gnu-4-45"
 run_dump_test "attr-gnu-4-51"
 
+set abis [concat o32 [expr {$has_newabi ? "n32 n64" : ""}]]
+foreach { abi } $abis {
+    run_ld_link_tests [list \
+	[list \
+	    "MIPS double-float relocatable ($abi)" \
+	    "$abi_ldflags($abi) -r" \
+	    "$abi_asflags($abi) -KPIC" \
+	    [list attr-gnu-4-1.s] \
+	    [list "readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-1-${abi}.o"] \
+	[list \
+	    "MIPS single-float relocatable ($abi)" \
+	    "$abi_ldflags($abi) -r" \
+	    "$abi_asflags($abi) -KPIC" \
+	    [list attr-gnu-4-2.s] \
+	    [list "readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-2-${abi}.o"] \
+	[list \
+	    "MIPS double-float shared library ($abi)" \
+	    "$abi_ldflags($abi) -shared tmpdir/attr-gnu-4-1-${abi}.o" \
+	    "" \
+	    "" \
+	    [list "readelf -A attr-gnu-4-1.gd"] \
+	    "libattr-gnu-4-1-${abi}.so"] \
+	[list \
+	    "MIPS single-float shared library ($abi)" \
+	    "$abi_ldflags($abi) -shared tmpdir/attr-gnu-4-2-${abi}.o" \
+	    "" \
+	    "" \
+	    [list "readelf -A attr-gnu-4-2.gd"] \
+	    "libattr-gnu-4-2-${abi}.so"] \
+	[list \
+	    "MIPS double-float executable 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o -Ltmpdir -lattr-gnu-4-1-${abi}" \
+	    "" \
+	    "" \
+	    [list "readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-11-1-${abi}"] \
+	[list \
+	    "MIPS double-float executable 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o tmpdir/libattr-gnu-4-1-${abi}.so" \
+	    "" \
+	    "" \
+	    [list "readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-11-2-${abi}"] \
+	[list \
+	    "MIPS single-float executable 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o -Ltmpdir -lattr-gnu-4-2-${abi}" \
+	    "" \
+	    "" \
+	    [list "readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-29-1-${abi}"] \
+	[list \
+	    "MIPS single-float executable 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o tmpdir/libattr-gnu-4-2-${abi}.so" \
+	    "" \
+	    "" \
+	    [list "readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-29-2-${abi}"] \
+	[list \
+	    "MIPS double-float executable with single-float library 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o -Ltmpdir -lattr-gnu-4-2-${abi}" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-12.ll" \
+		"readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-12-1-${abi}"] \
+	[list \
+	    "MIPS double-float executable with single-float library 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o tmpdir/libattr-gnu-4-2-${abi}.so" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-12.ll" \
+		"readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-12-2-${abi}"] \
+	[list \
+	    "MIPS double-float executable with single-float library 3 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o -Ltmpdir -lattr-gnu-4-1-${abi} -lattr-gnu-4-2-${abi}" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-12.ll" \
+		"readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-12-1-${abi}"] \
+	[list \
+	    "MIPS double-float executable with single-float library 4 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o tmpdir/libattr-gnu-4-1-${abi}.so tmpdir/libattr-gnu-4-2-${abi}.so" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-12.ll" \
+		"readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-12-2-${abi}"] \
+	[list \
+	    "MIPS double-float executable with single-float library 5 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o -Ltmpdir -lattr-gnu-4-2-${abi} -lattr-gnu-4-1-${abi}" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-12.ll" \
+		"readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-12-1-${abi}"] \
+	[list \
+	    "MIPS double-float executable with single-float library 6 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-1-${abi}.o tmpdir/libattr-gnu-4-2-${abi}.so tmpdir/libattr-gnu-4-1-${abi}.so" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-12.ll" \
+		"readelf -A attr-gnu-4-1.gd"] \
+	    "attr-gnu-4-12-2-${abi}"] \
+	[list \
+	    "MIPS single-float executable with double-float library 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o -Ltmpdir -lattr-gnu-4-1-${abi}" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-21.ll" \
+		"readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-21-1-${abi}"] \
+	[list \
+	    "MIPS single-float executable with double-float library 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o tmpdir/libattr-gnu-4-1-${abi}.so" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-21.ll" \
+		"readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-21-2-${abi}"] \
+	[list \
+	    "MIPS single-float executable with double-float library 3 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o -Ltmpdir -lattr-gnu-4-2-${abi} -lattr-gnu-4-1-${abi}" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-21.ll" \
+		"readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-21-1-${abi}"] \
+	[list \
+	    "MIPS single-float executable with double-float library 4 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o tmpdir/libattr-gnu-4-2-${abi}.so tmpdir/libattr-gnu-4-1-${abi}.so" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-21.ll" \
+		"readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-21-2-${abi}"] \
+	[list \
+	    "MIPS single-float executable with double-float library 5 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o -Ltmpdir -lattr-gnu-4-1-${abi} -lattr-gnu-4-2-${abi}" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-21.ll" \
+		"readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-21-1-${abi}"] \
+	[list \
+	    "MIPS single-float executable with double-float library 6 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/attr-gnu-4-2-${abi}.o tmpdir/libattr-gnu-4-1-${abi}.so tmpdir/libattr-gnu-4-2-${abi}.so" \
+	    "" \
+	    "" \
+	    [list \
+		"ld attr-gnu-4-21.ll" \
+		"readelf -A attr-gnu-4-2.gd"] \
+	    "attr-gnu-4-21-2-${abi}"]]
+}
+
 if { $linux_gnu } {
     run_ld_link_tests {
 	{"GOT and versioning 1"
@@ -669,3 +838,121 @@ foreach { abi } $abis {
 		"readelf -A export-class-call16-${abi}.gd"] \
 	    "export-class-call16-${abi}.so"]]
 }
+
+# Non-abicalls shared library interlinking error tests.
+set abis [concat o32 [expr {$has_newabi ? "n32 n64" : ""}]]
+foreach { abi } $abis {
+    run_ld_link_tests [list \
+	[list \
+	    "MIPS abicalls interlinking shared library ($abi)" \
+	    "$abi_ldflags($abi) -shared" \
+	    "$abi_asflags($abi) -KPIC" \
+	    [list abicalls-lib.s] \
+	    "" \
+	    "libabicalls-${abi}.so"] \
+	[list \
+	    "MIPS abicalls interlinking PIC relocatable ($abi)" \
+	    "$abi_ldflags($abi) -r" \
+	    "$abi_asflags($abi) -KPIC" \
+	    [list abicalls.s] \
+	    "" \
+	    "abicalls-pic-${abi}.o"] \
+	[list \
+	    "MIPS abicalls interlinking PLT relocatable ($abi)" \
+	    "$abi_ldflags($abi) -r" \
+	    "$abi_asflags($abi) -call_nonpic" \
+	    [list abicalls.s] \
+	    "" \
+	    "abicalls-plt-${abi}.o"] \
+	[list \
+	    "MIPS abicalls interlinking non-PIC relocatable ($abi)" \
+	    "$abi_ldflags($abi) -r" \
+	    "$abi_asflags($abi)" \
+	    [list abicalls.s] \
+	    "" \
+	    "abicalls-${abi}.o"] \
+	[list \
+	    "MIPS abicalls interlinking PIC executable 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/abicalls-pic-${abi}.o -Ltmpdir -labicalls-${abi}" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-pic-1-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PIC executable 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/abicalls-pic-${abi}.o tmpdir/libabicalls-${abi}.so" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-pic-2-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PIC executable 3 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 -Ltmpdir -labicalls-${abi} tmpdir/abicalls-pic-${abi}.o" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-pic-3-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PIC executable 4 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/libabicalls-${abi}.so tmpdir/abicalls-pic-${abi}.o" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-pic-4-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PLT executable 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/abicalls-plt-${abi}.o -Ltmpdir -labicalls-${abi}" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-plt-1-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PLT executable 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/abicalls-plt-${abi}.o tmpdir/libabicalls-${abi}.so" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-plt-2-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PLT executable 3 ($abi) tmpdir/abicalls-plt-${abi}.o" \
+	    "$abi_ldflags($abi) -e 0 -Ltmpdir -labicalls-${abi}" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-plt-3-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking PLT executable 4 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/libabicalls-${abi}.so tmpdir/abicalls-plt-${abi}.o" \
+	    "" \
+	    "" \
+	    "" \
+	    "abicalls-plt-4-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking non-PIC executable 1 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/abicalls-${abi}.o -Ltmpdir -labicalls-${abi}" \
+	    "" \
+	    "" \
+	    [list "ld abicalls.ll"] \
+	    "abicalls-1-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking non-PIC executable 2 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/abicalls-${abi}.o tmpdir/libabicalls-${abi}.so" \
+	    "" \
+	    "" \
+	    [list "ld abicalls.ll"] \
+	    "abicalls-2-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking non-PIC executable 3 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 -Ltmpdir -labicalls-${abi} tmpdir/abicalls-${abi}.o" \
+	    "" \
+	    "" \
+	    [list "ld abicalls.ll"] \
+	    "abicalls-3-${abi}"] \
+	[list \
+	    "MIPS abicalls interlinking non-PIC executable 4 ($abi)" \
+	    "$abi_ldflags($abi) -e 0 tmpdir/libabicalls-${abi}.so tmpdir/abicalls-${abi}.o" \
+	    "" \
+	    "" \
+	    [list "ld abicalls.ll"] \
+	    "abicalls-4-${abi}"]]
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]