From 7cd00957a57f8d8195baf7a85ea21b879bbbaf91 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Wed, 7 Aug 2019 10:20:56 +0100 Subject: [PATCH] Fix the binutils test for .NET assembly support so that it distinguishing between targets which do not support the x86 PE format at all, and those that do support it, but which do not recognise the .NET assembly variants. * 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 | 10 ++ binutils/testsuite/binutils-all/objdump.exp | 42 ++++++-- binutils/testsuite/gentestdlls.c | 105 ++++++++++++-------- 3 files changed, 110 insertions(+), 47 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index f60d5ffbb02..c785ad5a3f8 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,13 @@ +2019-08-07 Omair Majid + + * 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 PR 24876 diff --git a/binutils/testsuite/binutils-all/objdump.exp b/binutils/testsuite/binutils-all/objdump.exp index b46fd0a8bb4..c229194cbb6 100644 --- a/binutils/testsuite/binutils-all/objdump.exp +++ b/binutils/testsuite/binutils-all/objdump.exp @@ -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 } diff --git a/binutils/testsuite/gentestdlls.c b/binutils/testsuite/gentestdlls.c index b1463c01789..09bbe3319f0 100644 --- a/binutils/testsuite/gentestdlls.c +++ b/binutils/testsuite/gentestdlls.c @@ -29,8 +29,12 @@ #include #include #include +#include #include +#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; } -- 2.30.2