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
}
#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)
{
write_pe_signature (FILE* file)
{
char buffer[4];
+
buffer[0] = 'P';
buffer[1] = 'E';
buffer[2] = 0;
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;
}