public void WriteDynamicTable(JumpTable jumpTable) { // Writes internal state to jump table in-memory, after PtcJumpTable was deserialized. if (JumpTable.DynamicTableElems > 1) { throw new NotSupportedException(); } foreach (var tableEntry in _dynamicTable) { long guestAddress = tableEntry.GuestAddress; IndirectHostAddress indirectHostAddress = tableEntry.HostAddress; long hostAddress; if (indirectHostAddress == IndirectHostAddress.CallStub) { hostAddress = DirectCallStubs.IndirectCallStub(false).ToInt64(); } else if (indirectHostAddress == IndirectHostAddress.TailCallStub) { hostAddress = DirectCallStubs.IndirectCallStub(true).ToInt64(); } else { throw new InvalidOperationException(nameof(indirectHostAddress)); } int entry = tableEntry.EntryIndex; jumpTable.DynTable.SetEntry(entry); jumpTable.ExpandIfNeededDynamicTable(entry); IntPtr addr = jumpTable.GetEntryAddressDynamicTable(entry); Marshal.WriteInt64(addr, 0, guestAddress); Marshal.WriteInt64(addr, 8, hostAddress); } }
public void WriteDynamicTable(JumpTable jumpTable) { if (JumpTable.DynamicTableElems > 1) { throw new NotSupportedException(); } jumpTable.ExpandIfNeededDynamicTable(DynTableEnd); int entry = 0; foreach (var item in _dynamicTable) { entry += 1; long guestAddress = item.Key; IndirectHostAddress indirectHostAddress = item.Value; long hostAddress; if (indirectHostAddress == IndirectHostAddress.CallStub) { hostAddress = DirectCallStubs.IndirectCallStub(false).ToInt64(); } else if (indirectHostAddress == IndirectHostAddress.TailCallStub) { hostAddress = DirectCallStubs.IndirectCallStub(true).ToInt64(); } else { throw new InvalidOperationException(nameof(indirectHostAddress)); } IntPtr addr = jumpTable.GetEntryAddressDynamicTable(entry); Marshal.WriteInt64(addr, 0, guestAddress); Marshal.WriteInt64(addr, 8, hostAddress); } }
public static PtcJumpTable Deserialize(MemoryStream stream) { using (BinaryReader reader = new BinaryReader(stream, EncodingCache.UTF8NoBOM, true)) { var jumpTable = new List<TableEntry<DirectHostAddress>>(); int jumpTableCount = reader.ReadInt32(); for (int i = 0; i < jumpTableCount; i++) { int entryIndex = reader.ReadInt32(); long guestAddress = reader.ReadInt64(); DirectHostAddress hostAddress = (DirectHostAddress)reader.ReadInt32(); jumpTable.Add(new TableEntry<DirectHostAddress>(entryIndex, guestAddress, hostAddress)); } var dynamicTable = new List<TableEntry<IndirectHostAddress>>(); int dynamicTableCount = reader.ReadInt32(); for (int i = 0; i < dynamicTableCount; i++) { int entryIndex = reader.ReadInt32(); long guestAddress = reader.ReadInt64(); IndirectHostAddress hostAddress = (IndirectHostAddress)reader.ReadInt32(); dynamicTable.Add(new TableEntry<IndirectHostAddress>(entryIndex, guestAddress, hostAddress)); } var targets = new List<ulong>(); int targetsCount = reader.ReadInt32(); for (int i = 0; i < targetsCount; i++) { ulong address = reader.ReadUInt64(); targets.Add(address); } var dependants = new Dictionary<ulong, List<int>>(); int dependantsCount = reader.ReadInt32(); for (int i = 0; i < dependantsCount; i++) { ulong address = reader.ReadUInt64(); var entries = new List<int>(); int entriesCount = reader.ReadInt32(); for (int j = 0; j < entriesCount; j++) { int entry = reader.ReadInt32(); entries.Add(entry); } dependants.Add(address, entries); } var owners = new Dictionary<ulong, List<int>>(); int ownersCount = reader.ReadInt32(); for (int i = 0; i < ownersCount; i++) { ulong address = reader.ReadUInt64(); var entries = new List<int>(); int entriesCount = reader.ReadInt32(); for (int j = 0; j < entriesCount; j++) { int entry = reader.ReadInt32(); entries.Add(entry); } owners.Add(address, entries); } return new PtcJumpTable(jumpTable, dynamicTable, targets, dependants, owners); } }