diff options
author | jfrijters <jfrijters> | 2011-09-30 15:12:25 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2011-09-30 15:12:25 +0400 |
commit | fbf06d316a156ad5e272d328fc51fef6169dae7c (patch) | |
tree | 8ac17a54fe6667deabd7de0b566c7b7d16983b76 /reflect/Writer | |
parent | c3889a0ae0aaaf36d2604164a24cac62749b01a6 (diff) |
Added support for ARM.
Diffstat (limited to 'reflect/Writer')
-rw-r--r-- | reflect/Writer/ModuleWriter.cs | 26 | ||||
-rw-r--r-- | reflect/Writer/PEWriter.cs | 1 | ||||
-rw-r--r-- | reflect/Writer/TextSection.cs | 83 |
3 files changed, 71 insertions, 39 deletions
diff --git a/reflect/Writer/ModuleWriter.cs b/reflect/Writer/ModuleWriter.cs index ce78c095..8b19646c 100644 --- a/reflect/Writer/ModuleWriter.cs +++ b/reflect/Writer/ModuleWriter.cs @@ -102,6 +102,11 @@ namespace IKVM.Reflection.Writer writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x100000); break; + case ImageFileMachine.ARM: + writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM; + writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_32BIT_MACHINE; + writer.Headers.OptionalHeader.SizeOfStackReserve = moduleBuilder.GetStackReserve(0x100000); + break; case ImageFileMachine.AMD64: writer.Headers.FileHeader.Machine = IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64; writer.Headers.FileHeader.Characteristics |= IMAGE_FILE_HEADER.IMAGE_FILE_LARGE_ADDRESS_AWARE; @@ -181,12 +186,18 @@ namespace IKVM.Reflection.Writer } // Import Directory - writer.Headers.OptionalHeader.DataDirectory[1].VirtualAddress = code.ImportDirectoryRVA; - writer.Headers.OptionalHeader.DataDirectory[1].Size = code.ImportDirectoryLength; + if (code.ImportDirectoryLength != 0) + { + writer.Headers.OptionalHeader.DataDirectory[1].VirtualAddress = code.ImportDirectoryRVA; + writer.Headers.OptionalHeader.DataDirectory[1].Size = code.ImportDirectoryLength; + } // Import Address Table Directory - writer.Headers.OptionalHeader.DataDirectory[12].VirtualAddress = code.ImportAddressTableRVA; - writer.Headers.OptionalHeader.DataDirectory[12].Size = code.ImportAddressTableLength; + if (code.ImportAddressTableLength != 0) + { + writer.Headers.OptionalHeader.DataDirectory[12].VirtualAddress = code.ImportAddressTableRVA; + writer.Headers.OptionalHeader.DataDirectory[12].Size = code.ImportAddressTableLength; + } // COM Descriptor Directory writer.Headers.OptionalHeader.DataDirectory[14].VirtualAddress = code.ComDescriptorRVA; @@ -242,7 +253,10 @@ namespace IKVM.Reflection.Writer SectionHeader reloc = new SectionHeader(); reloc.Name = ".reloc"; reloc.VirtualAddress = rsrc.VirtualAddress + writer.ToSectionAlignment(rsrc.VirtualSize); - reloc.VirtualSize = ((uint)moduleBuilder.unmanagedExports.Count + 1) * 12; + if (imageFileMachine != ImageFileMachine.ARM) + { + reloc.VirtualSize = ((uint)moduleBuilder.unmanagedExports.Count + 1) * 12; + } reloc.PointerToRawData = rsrc.PointerToRawData + rsrc.SizeOfRawData; reloc.SizeOfRawData = writer.ToFileAlignment(reloc.VirtualSize); reloc.Characteristics = SectionHeader.IMAGE_SCN_MEM_READ | SectionHeader.IMAGE_SCN_CNT_INITIALIZED_DATA | SectionHeader.IMAGE_SCN_MEM_DISCARDABLE; @@ -271,7 +285,7 @@ namespace IKVM.Reflection.Writer // (i.e. there is an additional layer of indirection), so we add the offset to the pointer writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA + 0x20; } - else + else if (imageFileMachine != ImageFileMachine.ARM) { writer.Headers.OptionalHeader.AddressOfEntryPoint = code.StartupStubRVA; } diff --git a/reflect/Writer/PEWriter.cs b/reflect/Writer/PEWriter.cs index c3d32e13..21036f54 100644 --- a/reflect/Writer/PEWriter.cs +++ b/reflect/Writer/PEWriter.cs @@ -136,6 +136,7 @@ namespace IKVM.Reflection.Writer sealed class IMAGE_FILE_HEADER { public const WORD IMAGE_FILE_MACHINE_I386 = 0x014c; + public const WORD IMAGE_FILE_MACHINE_ARM = 0x01c4; public const WORD IMAGE_FILE_MACHINE_IA64 = 0x0200; public const WORD IMAGE_FILE_MACHINE_AMD64 = 0x8664; diff --git a/reflect/Writer/TextSection.cs b/reflect/Writer/TextSection.cs index 46472998..2cb91efd 100644 --- a/reflect/Writer/TextSection.cs +++ b/reflect/Writer/TextSection.cs @@ -71,13 +71,14 @@ namespace IKVM.Reflection.Writer { get { - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) + switch (peWriter.Headers.FileHeader.Machine) { - return 8; - } - else - { - return 16; + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: + return 8; + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: + return 0; + default: + return 16; } } } @@ -106,13 +107,13 @@ namespace IKVM.Reflection.Writer { get { - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) - { - return (MethodBodiesRVA + MethodBodiesLength + 3) & ~3U; - } - else + switch (peWriter.Headers.FileHeader.Machine) { - return (MethodBodiesRVA + MethodBodiesLength + 15) & ~15U; + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: + return (MethodBodiesRVA + MethodBodiesLength + 3) & ~3U; + default: + return (MethodBodiesRVA + MethodBodiesLength + 15) & ~15U; } } } @@ -219,7 +220,16 @@ namespace IKVM.Reflection.Writer internal uint ImportDirectoryLength { - get { return (ImportHintNameTableRVA - ImportDirectoryRVA) + 27; } + get + { + switch (peWriter.Headers.FileHeader.Machine) + { + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: + return 0; + default: + return (ImportHintNameTableRVA - ImportDirectoryRVA) + 27; + } + } } private uint ImportHintNameTableRVA @@ -258,30 +268,31 @@ namespace IKVM.Reflection.Writer { get { - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64) - { - return 12; - } - else if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64) + switch (peWriter.Headers.FileHeader.Machine) { - return 48; - } - else - { - return 6; + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: + return 6; + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_AMD64: + return 12; + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_IA64: + return 48; + default: + return 0; } } } private void WriteRVA(MetadataWriter mw, uint rva) { - if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) - { - mw.Write(rva); - } - else + switch (peWriter.Headers.FileHeader.Machine) { - mw.Write((ulong)rva); + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386: + case IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_ARM: + mw.Write(rva); + break; + default: + mw.Write((ulong)rva); + break; } } @@ -307,8 +318,11 @@ namespace IKVM.Reflection.Writer // Import Address Table AssertRVA(mw, ImportAddressTableRVA); - WriteRVA(mw, ImportHintNameTableRVA); - WriteRVA(mw, 0); + if (ImportAddressTableLength != 0) + { + WriteRVA(mw, ImportHintNameTableRVA); + WriteRVA(mw, 0); + } // CLI Header AssertRVA(mw, ComDescriptorRVA); @@ -398,7 +412,10 @@ namespace IKVM.Reflection.Writer // Import Directory AssertRVA(mw, ImportDirectoryRVA); - WriteImportDirectory(mw); + if (ImportDirectoryLength != 0) + { + WriteImportDirectory(mw); + } // alignment padding for (int i = (int)(StartupStubRVA - (ImportDirectoryRVA + ImportDirectoryLength)); i > 0; i--) @@ -427,7 +444,7 @@ namespace IKVM.Reflection.Writer mw.Write(peWriter.Headers.OptionalHeader.ImageBase + StartupStubRVA); mw.Write(peWriter.Headers.OptionalHeader.ImageBase + BaseRVA); } - else + else if (peWriter.Headers.FileHeader.Machine == IMAGE_FILE_HEADER.IMAGE_FILE_MACHINE_I386) { mw.Write((ushort)0x25FF); mw.Write((uint)peWriter.Headers.OptionalHeader.ImageBase + ImportAddressTableRVA); |