/// <summary> /// Encodes the specified memory stream. /// </summary> /// <param name="memoryStream">The memory stream.</param> /// <returns></returns> public bool Encode (MemoryStream memoryStream) { int org = 0; this.labels = new Dictionary<string, Instruction> (); BinaryWriter binaryWriter = new BinaryWriter (memoryStream); // The first pass does the computation/optimization // The second pass writes the content for (int pass = 0; pass < 2; pass++) { bool changed; if (pass == 1) this.Patch (); if (pass == 1) this.PatchSymbolOffsets (); do { changed = false; UInt32 offset = 0; bool bss = false; for (int i = 0; i < this.instructions.Count; i++) { Instruction instruction = this.instructions [i]; if (pass == 0) instruction.Index = i; if (instruction is OrgInstruction) { if ((UInt32) instruction.Value < offset) org = -((int) offset); else org = System.Convert.ToInt32 (instruction.Value); } else if (instruction is Bits32Instruction) this.bits32 = (bool) instruction.Value; else if (instruction is OffsetInstruction) { offset = (UInt32) instruction.Value; if (offset < binaryWriter.BaseStream.Length) throw new EngineException ("Wrong offset '" + offset.ToString () + "'."); while (pass == 1 && !bss && binaryWriter.BaseStream.Length < instruction.Offset) binaryWriter.Write ((byte) 0); } else if (instruction is AlignInstruction) { if (offset % (UInt32) instruction.Value != 0) offset += ((UInt32) instruction.Value - offset % (UInt32) instruction.Value); while (pass == 1 && !bss && binaryWriter.BaseStream.Length < instruction.Offset) binaryWriter.Write ((byte) 0); } else if (instruction is TimesInstruction) { TimesInstruction times = instruction as TimesInstruction; offset += times.Length; while (pass == 1 && !bss && binaryWriter.BaseStream.Length < instruction.Offset) binaryWriter.Write ((byte) times.Value); } if (instruction.Label.Equals (Assembly.FormatLabelName (START_BSS))) bss = true; if (pass == 0) { instruction.Offset = offset; if (instruction.Label.Length > 0) { if (this.labels.ContainsKey (instruction.Label)) throw new EngineException (string.Format ( "The label '{0}' has been defined more than once. Definition 1 = '{1}', Definition 2 = '{2}'", instruction.Label, this.labels [instruction.Label], instruction)); this.labels.Add (instruction.Label, instruction); } } if (pass == 1) { if (instruction is AddressOf) { AddressOf addressOf = instruction as AddressOf; addressOf.Value = (uint) (org + this.GetLabelAddress (addressOf.AddressOfLabel)); } if (instruction.Reference.Length > 0) { ((UInt32 []) instruction.Value) [0] = this.GetLabelAddress (instruction.Reference); if (!instruction.Relative) ((UInt32 []) instruction.Value) [0] = (UInt32) (org + ((UInt32 []) instruction.Value) [0]); } if (instruction.RMMemory != null && instruction.RMMemory.Reference.Length > 0) instruction.RMMemory.Displacement = (int) (org + this.GetLabelAddress (instruction.RMMemory.Reference) + instruction.RMMemory.DisplacementDelta); } if (pass == 0) { // Load End Address if (instruction.Label.Equals (Assembly.FormatLabelName (END_DATA))) this.multibootLoadEndAddress = (UInt32) (org + instruction.Offset); // BSS End Address if (instruction.Label.Equals (Assembly.FormatLabelName (END_BSS))) this.multibootBSSEndAddress = (UInt32) (org + instruction.Offset); } if (pass == 1 && !bss) instruction.Encode (this.bits32, binaryWriter); if (pass == 0) offset += instruction.Size (this.bits32); } } while (changed); } return true; }
public MetadataVisitor (Assembly asm) { this.asm = asm; }
/// <summary> /// Encodes the specified engine. /// </summary> /// <param name="engine">The engine.</param> /// <param name="target">The target.</param> /// <returns></returns> public bool Encode (Engine engine, string target) { this.symbols = new List<SharpOS.AOT.COFF.Symbol> (); this.data = new Assembly (); this.bss = new Assembly (); this.engine = engine; this.engine.Dump.Section (DumpSection.Encoding); #if PE this.AddPEHeader (); #else this.AddMultibootHeader (); #endif this.ALIGN (ALIGNMENT); this.LABEL (START_CODE); this.AddEntryPoint (); this.engine.Dump.Section (DumpSection.MethodEncode); foreach (Class _class in engine) { // interfaces don't have method bodies if (_class.IsInterface) continue; if (_class.IsGenericType) continue; GenerateIMTHelpers(_class); if (_class.IsInternal) continue; foreach (Method method in _class.Methods) { if (method.IsGenericType) continue; this.engine.Dump.MethodEncode (method); engine.SetStatusInformation (_class.ClassDefinition.Module.Assembly, _class.ClassDefinition.Module, _class.ClassDefinition, method.MethodDefinition); new AssemblyMethod (this, method).GetAssemblyCode (); engine.ClearStatusInformation (); } } this.engine.Dump.PopElement (); this.AddHelperFunctions (); this.ALIGN (ALIGNMENT); this.LABEL (END_CODE); this.AddData (); this.AddSymbols (); this.AddBSS (); this.ALIGN (ALIGNMENT); this.LABEL (THE_END); this.Save (target); return true; }