public void Patch1C() { var p = new Patch(0, 4, 3); var r = p.GetResult(2); Assert.Equal((ulong)0x10, r); }
public void Patch1B() { var p = new Patch(0, 4, 0); var r = p.GetResult(2); Assert.Equal((ulong)0x2, r); }
/// <summary> /// A request to patch already emitted code by storing the calculated virtual address value. /// </summary> /// <param name="linkType">Type of the link.</param> /// <param name="patches">The patches.</param> /// <param name="symbolVirtualAddress">The virtual virtualAddress of the method whose code is being patched.</param> /// <param name="symbolOffset">The value to store at the position in code.</param> /// <param name="symbolRelativeBase">The method relative base.</param> /// <param name="targetAddress">The position in code, where it should be patched.</param> /// <exception cref="System.InvalidOperationException"></exception> private void ApplyPatch(LinkType linkType, Patch[] patches, ExtendedLinkerSection section, long symbolVirtualAddress, long symbolOffset, long symbolRelativeBase, long targetAddress) { if (!SymbolsResolved) throw new InvalidOperationException(@"Can't apply patches - symbols not resolved."); // Calculate the patch offset long offset = (symbolVirtualAddress - section.VirtualAddress) + symbolOffset; if ((linkType & LinkType.KindMask) == LinkType.AbsoluteAddress) { // FIXME: Need a .reloc section with a relocation entry if the module is moved in virtual memory // the runtime loader must patch this link request, we'll fail it until we can do relocations. //throw new NotSupportedException(@".reloc section not supported."); } else { // Change the absolute into a relative offset targetAddress = targetAddress - (symbolVirtualAddress + symbolRelativeBase); } ulong value = Patch.GetResult(patches, (ulong)targetAddress); ulong mask = Patch.GetFinalMask(patches); // Save the stream position section.ApplyPatch(offset, linkType, value, mask, Endianness); }
/// <summary> /// Issues a linker request for the given runtime method. /// </summary> /// <param name="linkType">The type of link required.</param> /// <param name="patches">The patches.</param> /// <param name="symbolName">The symbol name that is being patched.</param> /// <param name="symbolOffset">The offset inside the method where the patch is placed.</param> /// <param name="relativeBase">The base virtualAddress, if a relative link is required.</param> /// <param name="targetSymbol">The linker symbol name to link against.</param> /// <param name="targetOffset">An offset to apply to the link target.</param> void ILinker.Link(LinkType linkType, Patch[] patches, string symbolName, int symbolOffset, int relativeBase, string targetSymbol, long targetOffset) { Debug.Assert(symbolName != null, @"Symbol can't be null."); if (symbolName == null) throw new ArgumentNullException(@"symbol"); List<LinkRequest> list; if (!linkRequests.TryGetValue(targetSymbol, out list)) { list = new List<LinkRequest>(); linkRequests.Add(targetSymbol, list); } list.Add(new LinkRequest(linkType, patches, symbolName, symbolOffset, relativeBase, targetSymbol, targetOffset)); }
public void Patch8() { var p = new Patch(1, 8, 0); Assert.Equal((ulong)0x1FE, p.Mask); }
public void Patch7() { var p = new Patch(1, 4, 0); Assert.Equal((ulong)0x1E, p.Mask); }
public void Patch6() { var p = new Patch(0, 64, 0); Assert.Equal((ulong)0xFFFFFFFFFFFFFFFF, p.Mask); }