Fix the binutils test for .NET assembly support so that it distinguishing between...
authorOmair Majid <omajid@redhat.com>
Wed, 7 Aug 2019 09:20:56 +0000 (10:20 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 7 Aug 2019 09:20:56 +0000 (10:20 +0100)
* testsuite/binutils-all/objdump.exp
(test_objdump_dotnet_assemblies): Fix test to distinguish errors
in parsing simple pei-i386 and pei-x86-64 vs parsing the newly
introduced machine types.
* testsuite/gentestdlls.c (write_simple_dll): New function.
(main): Generate simple and Linux-specific variants of pei-i386
and pei-x86-64 files so both can be used by tests.

binutils/ChangeLog
binutils/testsuite/binutils-all/objdump.exp
binutils/testsuite/gentestdlls.c

index f60d5ff..c785ad5 100644 (file)
@@ -1,3 +1,13 @@
+2019-08-07  Omair Majid  <omajid@redhat.com>
+
+       * testsuite/binutils-all/objdump.exp
+       (test_objdump_dotnet_assemblies): Fix test to distinguish errors
+       in parsing simple pei-i386 and pei-x86-64 vs parsing the newly
+       introduced machine types.
+       * testsuite/gentestdlls.c (write_simple_dll): New function.
+       (main): Generate simple and Linux-specific variants of pei-i386
+       and pei-x86-64 files so both can be used by tests.
+
 2019-08-07  Alan Modra  <amodra@gmail.com>
 
        PR 24876
index b46fd0a..c229194 100644 (file)
@@ -740,34 +740,62 @@ proc test_objdump_dotnet_assemblies {} {
 
     set test "dotnet-assemblies"
 
-    set got [binutils_run "$base_dir/testsuite/gentestdlls" "tmpdir"]
-    set want "wrote dotnet-linux-x86-64.dll"
+    set got [binutils_run "$base_dir/testsuite/gentestdlls" "tmpdir pei-i386 pei-x86-64"]
+    set want "wrote linux-pei-x86-64.dll"
+    # The test program is hardcoded to generate valid dlls on any target
     if ![regexp $want $got] then {
-       unsupported "$test"
+        fail "$test"
     }
 
-    set test "dotnet-assemblies (32-bit)"
+    # First test an ordinary x86 PE format DLL.
+    set test "dotnet-assemblies (ordinary x86 DLL)"
     set want "file format pei-i386"
-    set got [binutils_run $OBJDUMP "-x tmpdir/simple-i386.dll"]
+    set got [binutils_run $OBJDUMP "-x tmpdir/simple-pei-i386.dll"]
     if ![regexp $want $got] then {
        if [regexp "file format not recognized" $got] then {
+           # If the target does not recognize vanilla x86 PE format files
+           # then it cannot be expected to recognize .NET assemblies.  But
+           # this means that these tests are unsupported, rather than failures.
            unsupported $test
        } else {
            fail "$test"
        }
+       # In either case, if cannot pass this test, then
+       # there is no point in running any further tests.
+       return
+    }
+    pass $test
+
+    # Next check a 32-bit .NET DLL.
+    set test "dotnet-assemblies (32-bit .NET)"
+    set got [binutils_run $OBJDUMP "-x tmpdir/linux-pei-i386.dll"]
+    if ![regexp $want $got] then {
+       fail "$test"
     } else {
        pass $test
     }
 
-    set test "dotnet-assemblies (64-bit)"
+    # Next check an ordrinary x86_64 PE format DLL.
+    set test "dotnet-assemblies (ordinary x86_64 DLL)"
     set want "file format pei-x86-64"
-    set got [binutils_run $OBJDUMP "-x tmpdir/dotnet-linux-x86-64.dll"]
+    set got [binutils_run $OBJDUMP "-x tmpdir/simple-pei-x86-64.dll"]
     if ![regexp $want $got] then {
        if [regexp "file format not recognized" $got] then {
+           # If the target does not support 64-bit PE format
+           # files, then the following tests are unsupported.
            unsupported $test
        } else {
            fail "$test"
        }
+       return
+    }
+    pass $test
+
+    # Finally check a 64-bit .NET DLL.
+    set test "dotnet-assemblies (64-bit)"
+    set got [binutils_run $OBJDUMP "-x tmpdir/linux-pei-x86-64.dll"]
+    if ![regexp $want $got] then {
+       fail "$test"
     } else {
        pass $test
     }
index b1463c0..09bbe33 100644 (file)
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
+#define INCORRECT_USAGE 2
+#define IO_ERROR 3
+
 static void
 write_dos_header_and_stub (FILE* file)
 {
@@ -64,6 +68,7 @@ static void
 write_pe_signature (FILE* file)
 {
   char buffer[4];
+
   buffer[0] = 'P';
   buffer[1] = 'E';
   buffer[2] = 0;
@@ -83,70 +88,90 @@ write_coff_header (FILE* file, uint16_t machine)
   buffer[1] = machine >> 0x8;
   fwrite (buffer, 2, 1, file);
   memset (buffer, 0, sizeof (buffer));
-  /* NumberOfSections = 0 */
+  /* NumberOfSections = 0 */
   fwrite (buffer, 2, 1, file);
-  /* TimeDateStamp = 0 */
+  /* TimeDateStamp = 0 */
   fwrite (buffer, 4, 1, file);
-  /* PointerToSymbolTable = 0 */
+  /* PointerToSymbolTable = 0 */
   fwrite (buffer, 4, 1, file);
-  /* NumberOfSymbols = 0 */
+  /* NumberOfSymbols = 0 */
   fwrite (buffer, 4, 1, file);
-  /* OptionalHeaderSize = 0 */
+  /* OptionalHeaderSize = 0 */
   fwrite (buffer, 2, 1, file);
-  /* Characteristics = 0x2000 */
+  /* Characteristics = 0x2000 */
   buffer[0] = 0x00;
   buffer[1] = 0x20;
   fwrite (buffer, 2, 1, file);
   memset (buffer, 0 , sizeof (buffer));
 }
 
-int
-main (int argc, char** argv)
+static void
+write_simple_dll (const char* name, uint16_t machine)
 {
-  FILE* file;
-
-  if (argc < 2)
-    {
-      fprintf (stderr, "usage: %s output-directory\n", argv[0]);
-      exit (2);
-    }
-  if (chdir (argv[1]) != 0)
-    {
-      fprintf (stderr, "error: unable to change directory to %s\n", argv[0]);
-      exit (2);
-    }
+  FILE* file = fopen (name, "w");
 
-  /* Generate a simple DLL file.  */
-  file = fopen ("simple-i386.dll", "w");
   if (file == NULL)
     {
       fprintf (stderr, "error: unable to open file for writing\n");
-      exit (1);
+      exit (IO_ERROR);
     }
 
   write_dos_header_and_stub (file);
   write_pe_signature (file);
-  write_coff_header (file, 0x14c);
+  write_coff_header (file, machine);
   fclose (file);
-  printf ("wrote simple-i386.dll\n");
-
-  /* Generate a sample .NET Core on Linux dll file.  As opposed to the
-     more common DLLs that contain bytecode (CIL/MSIL), many .NET Core
-     DLLs are pre-compiled for specific architectures and platforms.
-     See https://github.com/jbevain/cecil/issues/337 for an example of
-     this value being used in practice.  */
-  file = fopen ("dotnet-linux-x86-64.dll", "w");
-  if (file == NULL)
+  file = NULL;
+  printf ("wrote %s\n", name);
+}
+
+int
+main (int argc, char** argv)
+{
+  char* program_name = argv[0];
+  char* output_directory = argv[1];
+
+  if (argc < 3)
     {
-      fprintf (stderr, "error: unable to open file for writing\n");
-      exit (1);
+      fprintf (stderr, "usage: %s output-directory format [format ...] \n\n", program_name);
+      fprintf (stderr, "format is an objdump-style format string, like pei-i386\n");
+      exit (INCORRECT_USAGE);
     }
 
-  write_dos_header_and_stub (file);
-  write_pe_signature (file);
-  write_coff_header (file, 0xfd1d /* x86-64 + Linux */);
-  fclose (file);
-  printf ("wrote dotnet-linux-x86-64.dll\n");
+  if (chdir (output_directory) != 0)
+    {
+      fprintf (stderr, "error: unable to change directory to %s\n", output_directory);
+      exit (INCORRECT_USAGE);
+    }
+
+  /* We generate a simple PEI format files, and then .NET Core on
+     Linux-style PEI files for a number of architectures.  As opposed
+     to the more common PEI files that contain bytecode (CIL/MSIL), many
+     .NET Core DLLs are pre-compiled for specific architectures and
+     platforms.  See https://github.com/jbevain/cecil/issues/337 for an
+     example of this value being used in practice.  */
+
+  for (int i = 2; i < argc; i++)
+    {
+      char* wanted_format = argv[i];
+
+      if (strcmp ("pei-i386", wanted_format) == 0)
+        {
+          write_simple_dll ("simple-pei-i386.dll", 0x14c);
+
+          write_simple_dll ("linux-pei-i386.dll", 0x14c ^ 0x7b79 /* i386 + Linux */);
+        }
+      else if (strcmp ("pei-x86-64", wanted_format) == 0)
+        {
+          write_simple_dll ("simple-pei-x86-64.dll", 0x8664);
+
+          write_simple_dll ("linux-pei-x86-64.dll", 0x8664 ^ 0x7b79 /* x86-64 + Linux */);
+        }
+      else
+        {
+          fprintf (stderr, "error: can't handle format %s\n", wanted_format);
+          exit (INCORRECT_USAGE);
+        }
+    }
 
   return 0;
 }