コード例 #1
0
ファイル: Assembly.cs プロジェクト: sharpos/SharpOS
		/// <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;
		}
コード例 #2
0
ファイル: Metadata.cs プロジェクト: sharpos/SharpOS
		public MetadataVisitor (Assembly asm)
		{
			this.asm = asm;
		}
コード例 #3
0
ファイル: Assembly.cs プロジェクト: sharpos/SharpOS
		/// <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;
		}