internal void Allocate(int instanceBufferSize, int relocationBufferSize, int importsBufferSize) { InstanceBufferSize = instanceBufferSize; RelocationBufferSize = relocationBufferSize; ImportsBufferSize = importsBufferSize; InstanceBuffer = MarshalUtil.AllocateMemory(InstanceBufferSize + 4); if (RelocationBufferSize > 0) { RelocationBuffer = MarshalUtil.AllocateMemory(RelocationBufferSize); } if (ImportsBufferSize > 0) { ImportsBuffer = MarshalUtil.AllocateMemory(ImportsBufferSize); } }
public unsafe void MakeRelocatable(Chunk chunk) { int importsBufferSize = 0; if (_imports.Count > 0) { importsBufferSize = (_imports.Count + 1) * 4; } int relocationBufferSize = 0; if (_relocations.Count > 0) { relocationBufferSize = (_relocations.Count + 1) * 4; } chunk.Allocate(_instanceBufferSize, relocationBufferSize, importsBufferSize); byte *instanceBuffer = (byte *)chunk.InstanceBuffer; byte *instanceBufferPosition = instanceBuffer; int blockCount = _blocks.Count; int * bookmarks = (int *)MarshalUtil.AllocateMemory(blockCount > 0x3FFFFFFF ? uint.MaxValue : (uint)(blockCount * 4)); int idx = 0; foreach (Block block in _blocks) { MarshalUtil.CopyMemory((IntPtr)instanceBufferPosition, block.Data, block.Size); bookmarks[idx++] = (int)(instanceBufferPosition - instanceBuffer); instanceBufferPosition += block.Size; } if (relocationBufferSize > 0) { int *relocationBuffer = (int *)chunk.RelocationBuffer; _relocations.Sort(new Comparison <Bookmark>((x, y) => BookmarkCompare(x, y) ? -1 : 1)); foreach (Bookmark relocation in _relocations) { int from = bookmarks[relocation.Index] + relocation.From; * relocationBuffer = from; if (IsBigEndian) { ByteSwap32((uint *)relocationBuffer); } int to = bookmarks[relocation.To]; if (IsBigEndian) { ByteSwap32((uint *)&to); } *(int *)(instanceBuffer + from) = to; relocationBuffer++; } *relocationBuffer = -1; } if (importsBufferSize > 0u) { int *importsBuffer = (int *)chunk.ImportsBuffer; _imports.Sort(new Comparison <Bookmark>((x, y) => BookmarkCompare(x, y) ? -1 : 1)); foreach (Bookmark import in _imports) { int from = bookmarks[import.Index] + import.From; * importsBuffer = from; if (IsBigEndian) { ByteSwap32((uint *)importsBuffer); } int to = import.To; if (IsBigEndian) { ByteSwap32((uint *)&to); } *(int *)(instanceBuffer + from) = to; importsBuffer++; } *importsBuffer = -1; } }