/// <inheritdoc /> public ISegmentReference SerializeMethodBody(MethodBodySerializationContext context, MethodDefinition method) { if (!(method.MethodBody is NativeMethodBody nativeMethodBody)) { return(SegmentReference.Null); } var provider = context.SymbolsProvider; // Create new raw code segment containing the native code. var segment = new CodeSegment(provider.ImageBase, nativeMethodBody.Code); // Process fixups. for (int i = 0; i < nativeMethodBody.AddressFixups.Count; i++) { // Import symbol. var fixup = nativeMethodBody.AddressFixups[i]; var symbol = provider.ImportSymbol(fixup.Symbol); // Create new fixup with imported symbol. segment.AddressFixups.Add(new AddressFixup(fixup.Offset, fixup.Type, symbol)); // Add base relocation when necessary. // TODO: keep architecture into account.. if (fixup.Type == AddressFixupType.Absolute32BitAddress) { var relocation = new BaseRelocation(RelocationType.HighLow, new RelativeReference(segment, (int)fixup.Offset)); provider.RegisterBaseRelocation(relocation); } } return(new SegmentReference(segment)); }
/// <inheritdoc /> public void RegisterBaseRelocation(BaseRelocation relocation) { if (_relocations.TryGetValue(relocation.Location, out var existing)) { if (existing.Type != relocation.Type) { throw new ArgumentException($"Conflicting base relocations for reference {relocation.Location}."); } } else { _relocations.Add(relocation.Location, relocation); } }
private static RelocationEntry CreateEntry(BaseRelocation relocation) =>
private static uint GetPageRva(BaseRelocation relocation) => (uint)(relocation.Location.Rva & ~0xFFF);
/// <summary> /// Adds a single base relocation to the buffer. /// </summary> /// <param name="relocation">The base relocation to add.</param> public void Add(BaseRelocation relocation) { _relocations.Add(relocation); _blocks = null; }
private static RelocationEntry CreateEntry(BaseRelocation relocation) => new RelocationEntry(relocation.Type, (int)(relocation.Location.Rva & 0xFFF));