protected override void Setup() { base.Setup(); symbol = MethodCompiler.Linker.GetSymbol(MethodCompiler.Method.FullName, SectionKind.Text); simLinker = MethodCompiler.Linker as SimLinker; }
public void AddSourceInformation(LinkerSymbol baseSymbol, long offset, string information) { lock (mylock3) { source.Add(new Tuple<LinkerSymbol, long, string>(baseSymbol, offset, information)); } }
public void AddInstruction(LinkerSymbol baseSymbol, long offset, SimInstruction instruction) { lock (mylock2) { instructions.Add(new Tuple<LinkerSymbol, long, SimInstruction>(baseSymbol, offset, instruction)); } }
public void ClearSymbolInformation(LinkerSymbol linkerSymbol) { lock (symbolData) { symbolData.Remove(linkerSymbol); } }
public void AddTargetSymbol(LinkerSymbol baseSymbol, int offset, string name) { lock (mylock1) { targetSymbols.Add(new Tuple<LinkerSymbol, int, string>(baseSymbol, offset, name)); } }
/// <summary> /// Allocates a symbol of the given name in the specified section. /// </summary> /// <param name="name">The name of the symbol.</param> /// <param name="section">The executable section to allocate From.</param> /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param> /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param> /// <returns> /// A stream, which can be used to populate the section. /// </returns> public virtual Stream Allocate(string name, SectionKind section, int size, int alignment) { try { Stream baseStream = Allocate(section, size, alignment); // Create a linker symbol for the name LinkerSymbol symbol = new LinkerSymbol(name, section, baseStream.Position); // Save the symbol for later use if (!symbols.ContainsKey(symbol.Name)) { symbols.Add(symbol.Name, symbol); } // Wrap the stream to catch premature disposal Stream result = new LinkerStream(symbol, baseStream, size); return(result); } catch (ArgumentException argx) { throw new LinkerException(String.Format(@"Symbol {0} defined multiple times.", name), argx); } }
public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset) { lock (mylock) { var linkRequest = new LinkRequest(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceSymbol, referenceOffset); LinkRequests.Add(linkRequest); } }
internal void SetFirst(LinkerSymbol symbol) { lock (mylock) { Symbols.Remove(symbol); Symbols.Insert(0, symbol); } }
internal LinkerSymbol GetSymbol(string name) { LinkerSymbol symbol = null; symbolLookup.TryGetValue(name, out symbol); return(symbol); }
/// <summary> /// Initializes a new instance of the <see cref="LinkerStream"/> class. /// </summary> /// <param name="symbol">The linker symbol created by this stream.</param> /// <param name="stream">The stream provided by the actual linker instance.</param> /// <param name="length">The length of the symbol. Set to zero, if length is unknown.</param> public LinkerStream(LinkerSymbol symbol, Stream stream, long length) { if (symbol == null) throw new ArgumentNullException(@"symbol"); if (stream == null) throw new ArgumentNullException(@"stream"); this.length = length; this.start = stream.Position; this.symbol = symbol; this.stream = stream; }
protected override void Setup() { base.Setup(); symbol = MethodCompiler.Linker.GetSymbol(MethodCompiler.Method.FullName, SectionKind.Text); stage = MethodCompiler.Compiler.PostCompilePipeline.FindFirst<SimLinkerFinalizationStage>() as SimLinkerFinalizationStage; Debug.Assert(stage != null); stage.ClearSymbolInformation(symbol); }
/// <summary> /// Initializes a new instance of LinkRequest. /// </summary> /// <param name="linkType">Type of the link.</param> /// <param name="patchType">Type of the patch.</param> /// <param name="patchSymbol">The patch symbol.</param> /// <param name="patchOffset">The patch offset.</param> /// <param name="referenceSymbol">The reference symbol.</param> /// <param name="referenceOffset">The reference offset.</param> /// public LinkRequest(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, LinkerSymbol referenceSymbol, int referenceOffset) { Debug.Assert(patchSymbol != null); Debug.Assert(referenceSymbol != null); LinkType = linkType; PatchType = patchType; PatchSymbol = patchSymbol; PatchOffset = patchOffset; ReferenceSymbol = referenceSymbol; ReferenceOffset = referenceOffset; }
/// <summary> /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected override void Dispose(bool disposing) { if (stream != null && symbol != null) { // Fix the linker symbol size symbol.Length = Position; // Clear the stream & symbol stream = null; symbol = null; } base.Dispose(disposing); }
/// <summary> /// Initializes a new instance of LinkRequest. /// </summary> /// <param name="linkType">Type of the link.</param> /// <param name="patchType">Type of the patch.</param> /// <param name="patchSymbol">The patch symbol.</param> /// <param name="patchOffset">The patch offset.</param> /// <param name="relativeBase">The relative base.</param> /// <param name="referenceSymbol">The reference symbol.</param> /// <param name="referenceOffset">The reference offset.</param> public LinkRequest(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset) { Debug.Assert(patchSymbol != null); Debug.Assert(referenceSymbol != null); Debug.Assert(patchType != null); this.LinkType = linkType; this.PatchType = patchType; this.PatchSymbol = patchSymbol; this.PatchOffset = patchOffset; this.RelativeBase = relativeBase; this.ReferenceSymbol = referenceSymbol; this.ReferenceOffset = referenceOffset; }
/// <summary> /// Initializes a new instance of the <see cref="LinkerStream"/> class. /// </summary> /// <param name="symbol">The linker symbol created by this stream.</param> /// <param name="stream">The stream provided by the actual linker instance.</param> /// <param name="length">The length of the symbol. Set to zero, if length is unknown.</param> public LinkerStream(LinkerSymbol symbol, Stream stream, long length) { if (symbol == null) { throw new ArgumentNullException(@"symbol"); } if (stream == null) { throw new ArgumentNullException(@"stream"); } this.length = length; this.start = stream.Position; this.symbol = symbol; this.stream = stream; }
protected LinkerSymbol CreateSymbol(string name, SectionKind kind, uint alignment) { lock (mylock) { var section = Sections[(int)kind]; Debug.Assert(section != null); var symbol = section.GetSymbol(name); if (symbol == null) { symbol = new LinkerSymbol(name, kind, alignment); section.AddLinkerObject(symbol); } symbol.Alignment = alignment != 0 ? alignment : 0; return(symbol); } }
private SymbolInfo GetSymbolInfo(LinkerSymbol linkerSymbol) { SymbolInfo symbolInfo = null; lock (symbolData) { if (!symbolData.TryGetValue(linkerSymbol, out symbolInfo)) { symbolInfo = new SymbolInfo(); symbolData.Add(linkerSymbol, symbolInfo); } } return symbolInfo; }
public void AddSourceInformation(LinkerSymbol baseSymbol, long offset, string information) { var symbolInfo = GetSymbolInfo(baseSymbol); symbolInfo.source.Add(new Tuple<long, string>(offset, information)); }
public void AddTargetSymbol(LinkerSymbol baseSymbol, int offset, string name) { var symbolInfo = GetSymbolInfo(baseSymbol); symbolInfo.targetSymbols.Add(new Tuple<int, string>(offset, name)); }
public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, string referenceSymbol, SectionKind patchRelativeBase, int referenceOffset) { var referenceObject = GetSymbol(referenceSymbol, patchRelativeBase); Link(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceObject, referenceOffset); }
/// <summary> /// Allocates a symbol of the given name in the specified section. /// </summary> /// <param name="name">The name of the symbol.</param> /// <param name="section">The executable section to allocate from.</param> /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param> /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param> /// <returns> /// A stream, which can be used to populate the section. /// </returns> Stream ILinker.Allocate(string name, SectionKind section, int size, int alignment) { ExtendedLinkerSection linkerSection = (ExtendedLinkerSection)GetSection(section); Stream stream = linkerSection.Allocate(size, alignment); // Create a linker symbol for the name LinkerSymbol symbol = new LinkerSymbol(name, section, stream.Position); //symbol.VirtualAddress = linkerSection.VirtualAddress + stream.Position; symbols.Add(symbol.Name, symbol); return new LinkerStream(symbol, stream, size); }
public SymbolEntry(LinkerSymbol linkerSymbol, bool display32) { this.LinkerSymbol = linkerSymbol; this.display32 = display32; this.SectionKind = linkerSymbol.SectionKind.ToString(); }
protected unsafe void AddVmCall(IDictionary<string, LinkerSymbol> virtualMachineCalls, Delegate handler, string method) { IntPtr allocate = Marshal.GetFunctionPointerForDelegate(handler); long virtualAddress = allocate.ToInt64(); //Trace.WriteLine(String.Format("\t{0} at 0x{1:x08}", method, virtualAddress)); LinkerSymbol symbol = new LinkerSymbol(method, SectionKind.Text, virtualAddress); symbol.VirtualAddress = new IntPtr(symbol.SectionAddress); virtualMachineCalls.Remove(method); virtualMachineCalls.Add(method, symbol); }
/// <summary> /// Allocates a symbol of the given name in the specified section. /// </summary> /// <param name="name">The name of the symbol.</param> /// <param name="section">The executable section to allocate From.</param> /// <param name="size">The number of bytes to allocate. If zero, indicates an unknown amount of memory is required.</param> /// <param name="alignment">The alignment. A value of zero indicates the use of a default alignment for the section.</param> /// <returns> /// A stream, which can be used to populate the section. /// </returns> public virtual Stream Allocate(string name, SectionKind section, int size, int alignment) { try { Stream baseStream = Allocate(section, size, alignment); // Create a linker symbol for the name LinkerSymbol symbol = new LinkerSymbol(name, section, baseStream.Position); // Save the symbol for later use symbols.Add(symbol.Name, symbol); // Wrap the stream to catch premature disposal Stream result = new LinkerStream(symbol, baseStream, size); return result; } catch (ArgumentException argx) { throw new LinkerException(String.Format(@"Symbol {0} defined multiple times.", name), argx); } }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); Linker.CreateSymbol(Multiboot0695Stage.MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); return; } var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>(); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var esp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ESP); var MultibootEAX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEAX); var multibootEBX = Operand.CreateUnmanagedSymbolPointer(TypeSystem, Multiboot0695Stage.MultibootEBX); var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); var stackTop = Operand.CreateConstant(TypeSystem.BuiltIn.I4, STACK_ADDRESS); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeadBlock(block); var ctx = new Context(block); // Setup the stack and place the sentinel on the stack to indicate the start of the stack ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, esp, zero, stackTop); ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, ebp, zero, zero); // Place the multiboot address into a static field ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, MultibootEAX, zero, eax); ctx.AppendInstruction(X86.MovStore, InstructionSize.Size32, null, multibootEBX, zero, ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, 0); }
internal void AddLinkerObject(LinkerSymbol symbol) { Symbols.Add(symbol); symbolLookup.Add(symbol.Name, symbol); }
private LinkerSymbol CreateTypeDefinition(MosaType type, LinkerSymbol assemblyTableSymbol) { // Emit type name var typeNameSymbol = EmitStringWithLength(type.FullName + Metadata.NameString, type.FullName); // Emit type table var typeTableSymbol = Linker.CreateSymbol(type.FullName + Metadata.TypeDefinition, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0); var writer1 = new EndianAwareBinaryWriter(typeTableSymbol.Stream, Architecture.Endianness); // 1. Pointer to Name Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, typeNameSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 2. Pointer to Custom Attributes if (type.CustomAttributes.Count > 0) { var customAttributeListSymbol = CreateCustomAttributesTable(type); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, customAttributeListSymbol, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 3. Type Code & Attributes writer1.Write(((uint)type.TypeCode << 24) + (uint)type.TypeAttributes, TypeLayout.NativePointerSize); // 4. Size writer1.Write((uint)TypeLayout.GetTypeSize(type), TypeLayout.NativePointerSize); // 5. Pointer to Assembly Definition Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, assemblyTableSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 6. Pointer to Parent Type if (type.BaseType != null) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, type.BaseType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 7. Pointer to Declaring Type if (type.DeclaringType != null) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, type.DeclaringType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 8. Pointer to Element Type if (type.ElementType != null) { Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, type.ElementType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 9. Constructor that accepts no parameters, if any, for this type foreach (var method in type.Methods) { if (!method.Name.Equals(".ctor") || !(method.Signature.Parameters.Count == 0) || method.HasOpenGenericParams) continue; Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, method.FullName + Metadata.MethodDefinition, SectionKind.ROData, 0); break; } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 10. Properties (if any) if (type.Properties.Count > 0) { var propertiesSymbol = CreatePropertyDefinitions(type); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, propertiesSymbol, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // If the type is not an interface continue, otherwise just pad until the end if (!type.IsInterface) { // 11. Fields (if any) if (type.Fields.Count > 0) { var fieldsSymbol = CreateFieldDefinitions(type); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, fieldsSymbol, 0); } writer1.WriteZeroBytes(TypeLayout.NativePointerSize); var interfaces = GetInterfaces(type); // If the type doesn't use interfaces then skip 9 and 10 if (interfaces.Count > 0) { // 12. Pointer to Interface Slots var interfaceSlotTableSymbol = CreateInterfaceSlotTable(type, interfaces); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, interfaceSlotTableSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); // 13. Pointer to Interface Bitmap var interfaceBitmapSymbol = CreateInterfaceBitmap(type, interfaces); Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, interfaceBitmapSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); } else { // Fill 12 and 13 with zeros writer1.WriteZeroBytes(TypeLayout.NativePointerSize * 2); } // For the next part we'll need to get the list of methods from the MosaTypeLayout var methodList = TypeLayout.GetMethodTable(type) ?? new List<MosaMethod>(); // 14. Number of Methods writer1.Write(methodList.Count, TypeLayout.NativePointerSize); // 15. Pointer to Method Definitions foreach (var method in methodList) { // Create definition and get the symbol var methodDefinitionSymbol = CreateMethodDefinition(method); // Link Linker.Link(LinkType.AbsoluteAddress, NativePatchType, typeTableSymbol, (int)writer1.Position, 0, methodDefinitionSymbol, 0); writer1.WriteZeroBytes(TypeLayout.NativePointerSize); } } else { // Fill 11, 12, 13, 14 with zeros, 15 can be left out. writer1.WriteZeroBytes(TypeLayout.NativePointerSize * 4); } // Return typeTableSymbol for linker usage return typeTableSymbol; }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); return; } var typeInitializerSchedulerStage = Compiler.Pipeline.FindFirst<TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var basicBlocks = new BasicBlocks(); var instructionSet = new InstructionSet(25); var ctx = instructionSet.CreateNewBlock(basicBlocks); basicBlocks.AddHeaderBlock(ctx.BasicBlock); // set sentinal on the stack to indicate the start of the stack var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero); // store multiboot registers eax and ebx at 0x200000 and 0x200004 respectively ctx.AppendInstruction(X86.Mov, ecx, Operand.CreateConstantSignedInt(TypeSystem, 0x200000)); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 4), ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, instructionSet); }
protected override void Run() { if (multibootMethod == null) { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); Linker.EntryPoint = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); WriteMultibootHeader(); Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); return; } var typeInitializerSchedulerStage = Compiler.PostCompilePipeline.FindFirst<TypeInitializerSchedulerStage>(); var ecx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.ECX); var eax = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EAX); var ebx = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBX); var ebp = Operand.CreateCPURegister(TypeSystem.BuiltIn.I4, GeneralPurposeRegister.EBP); var multibootEax = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEAX); var multibootEbx = Operand.CreateUnmanagedSymbolPointer(TypeSystem, MultibootEBX); var basicBlocks = new BasicBlocks(); var block = basicBlocks.CreateBlock(); basicBlocks.AddHeaderBlock(block); var ctx = new Context(block); // set sentinel on the stack to indicate the start of the stack var zero = Operand.CreateConstant(TypeSystem.BuiltIn.I4, 0); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ebp, 0), zero); ctx.AppendInstruction(X86.Mov, ecx, multibootEax); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), eax); ctx.AppendInstruction(X86.Mov, ecx, multibootEbx); ctx.AppendInstruction(X86.Mov, Operand.CreateMemoryAddress(TypeSystem.BuiltIn.I4, ecx, 0), ebx); // call type initializer var entryPoint = Operand.CreateSymbolFromMethod(TypeSystem, typeInitializerSchedulerStage.TypeInitializerMethod); ctx.AppendInstruction(X86.Call, null, entryPoint); // should never get here ctx.AppendInstruction(X86.Ret); Compiler.CompileMethod(multibootMethod, basicBlocks, 0); }
public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset) { lock (mylock) { var linkRequest = new LinkRequest(linkType, patchType, patchSymbol, patchOffset, relativeBase, referenceSymbol, referenceOffset); //LinkRequests.Add(linkRequest); patchSymbol.AddPatch(linkRequest); } }
public void Link(LinkType linkType, PatchType patchType, string patchSymbolName, SectionKind patchKind, int patchOffset, int relativeBase, LinkerSymbol referenceSymbol, int referenceOffset) { var patchObject = GetSymbol(patchSymbolName, patchKind); Link(linkType, patchType, patchObject, patchOffset, relativeBase, referenceSymbol, referenceOffset); }
protected LinkerSymbol CreateSymbol(string name, SectionKind kind, uint alignment) { lock (mylock) { var section = Sections[(int)kind]; Debug.Assert(section != null); var symbol = section.GetSymbol(name); if (symbol == null) { symbol = new LinkerSymbol(name, kind, alignment); section.AddLinkerObject(symbol); } symbol.Alignment = alignment != 0 ? alignment : 0; return symbol; } }
protected override void RunPreCompile() { multibootHeader = Linker.CreateSymbol(MultibootHeaderSymbolName, SectionKind.Text, 1, 0x30); Linker.CreateSymbol(MultibootEAX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); Linker.CreateSymbol(MultibootEBX, SectionKind.BSS, Architecture.NativeAlignment, Architecture.NativePointerSize); multibootMethod = Compiler.CreateLinkerMethod("MultibootInit"); var multibootSymbol = Linker.GetSymbol(multibootMethod.FullName, SectionKind.Text); Linker.EntryPoint = multibootSymbol; }
public void AddInstruction(LinkerSymbol baseSymbol, long offset, SimInstruction instruction) { var symbolInfo = GetSymbolInfo(baseSymbol); symbolInfo.instructions.Add(new Tuple<long, SimInstruction>(offset, instruction)); }
public void Link(LinkType linkType, PatchType patchType, LinkerSymbol patchSymbol, int patchOffset, SectionKind referenceKind, string referenceSymbolName, int referenceOffset) { var referenceObject = GetSymbol(referenceSymbolName, referenceKind); Link(linkType, patchType, patchSymbol, patchOffset, referenceObject, referenceOffset); }
private void WriteArgument(EndianAwareBinaryWriter writer, LinkerSymbol symbol, MosaType type, object value) { if (type.IsEnum) type = type.GetEnumUnderlyingType(); switch (type.TypeCode) { // 1 byte case MosaTypeCode.Boolean: writer.Write((bool)value); break; case MosaTypeCode.U1: writer.Write((byte)value); break; case MosaTypeCode.I1: writer.Write((sbyte)value); break; // 2 bytes case MosaTypeCode.Char: writer.Write((char)value); break; case MosaTypeCode.U2: writer.Write((ushort)value); break; case MosaTypeCode.I2: writer.Write((short)value); break; // 4 bytes case MosaTypeCode.U4: writer.Write((uint)value); break; case MosaTypeCode.I4: writer.Write((int)value); break; case MosaTypeCode.R4: writer.Write((float)value); break; // 8 bytes case MosaTypeCode.U8: writer.Write((ulong)value); break; case MosaTypeCode.I8: writer.Write((long)value); break; case MosaTypeCode.R8: writer.Write((double)value); break; // SZArray case MosaTypeCode.SZArray: Debug.Assert(value is MosaCustomAttribute.Argument[]); var arr = (MosaCustomAttribute.Argument[])value; writer.Write(arr.Length, TypeLayout.NativePointerSize); foreach (var elem in arr) WriteArgument(writer, symbol, elem.Type, elem.Value); break; // String case MosaTypeCode.String: // Since strings are immutable, make it an object that we can just use var str = (string)value; Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, (int)writer.Position, 0, "System.String" + Metadata.TypeDefinition, SectionKind.ROData, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize * 2); writer.Write(str.Length, TypeLayout.NativePointerSize); writer.Write(System.Text.Encoding.Unicode.GetBytes(str)); break; default: if (type.FullName == "System.Type") { var valueType = (MosaType)value; Linker.Link(LinkType.AbsoluteAddress, NativePatchType, symbol, (int)writer.Position, 0, valueType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0); writer.WriteZeroBytes(TypeLayout.NativePointerSize); } else throw new NotSupportedException(); break; } }
public void SetFirst(LinkerSymbol symbol) { var section = LinkerSections[(int)symbol.SectionKind]; section.SetFirst(symbol); }