public override void Read(PeReader rdr) { rdr.SetPosition(hdr.WindowsSpecificFieldsOffset); if (hdr.Type == ExecutableType.PE32Plus) { imgBas = rdr.ReadUInt64(); sectA = rdr.ReadUInt32(); fA = rdr.ReadUInt32(); maOs = rdr.ReadUInt16(); miOs = rdr.ReadUInt16(); maImg = rdr.ReadUInt16(); miImg = rdr.ReadUInt16(); maSs = rdr.ReadUInt16(); miSs = rdr.ReadUInt16(); winVer = rdr.ReadUInt32(); sImg = rdr.ReadUInt32(); sHdr = rdr.ReadUInt32(); cs = rdr.ReadUInt32(); Ss = (WindowsSubsystem)rdr.ReadUInt16(); dll = (DLLCharacteristics)rdr.ReadUInt16(); sSr = rdr.ReadUInt64(); sSc = rdr.ReadUInt64(); sHr = rdr.ReadUInt64(); sHc = rdr.ReadUInt64(); ldrF = rdr.ReadUInt32(); noDd = rdr.ReadUInt32(); } else { imgBas = rdr.ReadUInt32(); sectA = rdr.ReadUInt32(); fA = rdr.ReadUInt32(); maOs = rdr.ReadUInt16(); miOs = rdr.ReadUInt16(); maImg = rdr.ReadUInt16(); miImg = rdr.ReadUInt16(); maSs = rdr.ReadUInt16(); miSs = rdr.ReadUInt16(); winVer = rdr.ReadUInt32(); sImg = rdr.ReadUInt32(); sHdr = rdr.ReadUInt32(); cs = rdr.ReadUInt32(); Ss = (WindowsSubsystem)rdr.ReadUInt16(); dll = (DLLCharacteristics)rdr.ReadUInt16(); sSr = rdr.ReadUInt32(); sSc = rdr.ReadUInt32(); sHr = rdr.ReadUInt32(); sHc = rdr.ReadUInt32(); ldrF = rdr.ReadUInt32(); noDd = rdr.ReadUInt32(); } }
/// <summary> /// Call the compiler with appropriate arguments for compiling the <paramref name="Unit"/> /// </summary> /// <remarks> /// This actually calls the linker as well, so that a shared library is built rather than just object code /// </remarks> /// <param name="Unit">Unit to compile</param> /// <param name="Architecture">Target architecture</param> /// <param name="WindowsSubsystem">Windows Subsystem to build for</param> public static void Compile(Unit Unit, Architecture Architecture = Architecture.Generic, WindowsSubsystem WindowsSubsystem = WindowsSubsystem.Console) { String arch; switch (Architecture) { case Architecture.Generic: arch = "-mtune=generic"; break; case Architecture.Native: default: arch = "-march=native"; break; } try { Process GnatMake = new Process(); ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = "gnatmake"; StartInfo.EnvironmentVariables["ADA_INCLUDE_PATH"] = ""; StartInfo.EnvironmentVariables["ADA_OBJECTS_PATH"] = ""; switch (Environment.OSVersion.Platform) { case (PlatformID)1: case (PlatformID)2: case (PlatformID)3: switch (WindowsSubsystem) { case WindowsSubsystem.Windows: StartInfo.Arguments = "-shared -shared-libgcc -fPIC -mwindows " + arch + " " + String.Join(' ', Unit.GetFiles()) + Unit.LinkerArguments; break; case WindowsSubsystem.Console: default: StartInfo.Arguments = "-shared -shared-libgcc -fPIC -mconsole " + arch + " " + String.Join(' ', Unit.GetFiles()) + Unit.LinkerArguments; break; } break; case PlatformID.Unix: StartInfo.Arguments = "-shared -fPIC " + arch + " " + String.Join(' ', Unit.GetFiles()) + Unit.LinkerArguments; break; default: throw new PlatformNotSupportedException("Unable to determine what the Operating System is"); } GnatMake.StartInfo = StartInfo; GnatMake.Start(); GnatMake.WaitForExit(); // We need to wait here, because otherwise units will be compiled before their dependencies are finished compiling. That's bad. GnatMake.Dispose(); } catch (Win32Exception) { throw new MissingGNATProgramException("gnatmake"); } if (Unit is PackageUnit || Unit is SubroutineUnit) { Process CreateLibrary; // Linking is a very different procedure on different systems, so figure out what we're supposed to do switch (Environment.OSVersion.Platform) { case (PlatformID)1: case (PlatformID)2: case (PlatformID)3: CreateLibrary = Process.Start("gcc", "-shared " + Unit.Name + ".o " + Unit.LinkerArguments + " -o " + Unit.Name + ".dll -Wl,--export-all-symbols"); break; case PlatformID.Unix: CreateLibrary = Process.Start("ld", "-shared " + Unit.Name + ".o " + Unit.LinkerArguments + " -o " + Unit.Name + ".so"); break; default: throw new PlatformNotSupportedException("Unable to determine what the Operating System is"); } CreateLibrary.WaitForExit(); //? We might not need to wait here CreateLibrary.Dispose(); } }