/// <summary> /// A request to patch already emitted code by storing the calculated virtualAddress value. /// </summary> /// <param name="linkType">Type of the link.</param> /// <param name="methodAddress">The virtual virtualAddress of the method whose code is being patched.</param> /// <param name="methodOffset">The value to store at the position in code.</param> /// <param name="methodRelativeBase">The method relative base.</param> /// <param name="targetAddress">The position in code, where it should be patched.</param> protected override void ApplyPatch(LinkType linkType, long methodAddress, long methodOffset, long methodRelativeBase, long targetAddress) { if (this.symbolsResolved == false) { throw new InvalidOperationException(@"Can't apply patches - symbols not resolved."); } // Retrieve the text section PortableExecutableLinkerSection text = (PortableExecutableLinkerSection)GetSection(SectionKind.Text); // Calculate the patch offset long offset = (methodAddress - text.VirtualAddress.ToInt64()) + methodOffset; 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 - (methodAddress + methodRelativeBase); } // Save the stream position text.ApplyPatch(offset, linkType, targetAddress); }
/// <summary> /// Allocates a symbol of the given name in the specified section. /// </summary> /// <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> protected override Stream Allocate(SectionKind section, int size, int alignment) { PortableExecutableLinkerSection linkerSection = (PortableExecutableLinkerSection)GetSection(section); return(linkerSection.Allocate(size, alignment)); }