|
|
//----------------------------------------------------------------------------
//
// General ADDR routines.
//
// Copyright (C) Microsoft Corporation, 1997-2002.
//
//----------------------------------------------------------------------------
#include "ntsdp.hpp"
SHORT g_LastSelector = -1; ULONG64 g_LastBaseOffset;
void dprintAddr(PADDR Addr) { switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER))) { case ADDR_V86 | FLAT_BASIS: dprintf("%s ", FormatAddr64(Addr->flat)); break; case ADDR_V86: case ADDR_16: dprintf("%04x:%04x ", Addr->seg, (USHORT)Addr->off); break; case ADDR_1632: dprintf("%04x:%08lx ", Addr->seg, (ULONG)Addr->off); break; case ADDR_1664: dprintf("%04x:%s ", Addr->seg, FormatAddr64(Addr->off)); break; case ADDR_FLAT: dprintf("%s ", FormatAddr64(Addr->off)); break; } }
void sprintAddr(PSTR* Buffer, PADDR Addr) { switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER))) { case ADDR_V86 | FLAT_BASIS: sprintf(*Buffer, "%s ", FormatAddr64(Addr->flat)); break; case ADDR_V86: case ADDR_16: sprintf(*Buffer, "%04x:%04x ", Addr->seg, (USHORT)Addr->off); break; case ADDR_1632: sprintf(*Buffer, "%04x:%08lx ", Addr->seg, (ULONG)Addr->off); break; case ADDR_1664: sprintf(*Buffer, "%04x:%s ", Addr->seg, FormatAddr64(Addr->off)); break; case ADDR_FLAT: sprintf(*Buffer, "%s ", FormatAddr64(Addr->off)); break; } while (**Buffer) { (*Buffer)++; } }
void MaskOutAddr(ULONG Mask, PADDR Addr) { switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER))) { case ADDR_V86 | FLAT_BASIS: MaskOut(Mask, "%s ", FormatAddr64(Addr->flat)); break; case ADDR_V86: case ADDR_16: MaskOut(Mask, "%04x:%04x ", Addr->seg, (USHORT)Addr->off); break; case ADDR_1632: MaskOut(Mask, "%04x:%08lx ", Addr->seg, (ULONG)Addr->off); break; case ADDR_1664: MaskOut(Mask, "%04x:%s ", Addr->seg, FormatAddr64(Addr->off)); break; case ADDR_FLAT: MaskOut(Mask, "%s ", FormatAddr64(Addr->off)); break; } }
void ComputeNativeAddress(PADDR Addr) { switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER))) { case ADDR_V86 | FLAT_BASIS: // Segment isn't actually used.
Addr->seg = 0; Addr->off = Flat(*Addr) & 0xffff; break; case ADDR_V86: Addr->off = Flat(*Addr) - ((ULONG64)Addr->seg << 4); if (Addr->off > 0xffff) { ULONG64 excess = 1 + ((Addr->off - 0xffffL) >> 4); Addr->seg += (USHORT)excess; Addr->off -= excess << 4; } break;
case ADDR_16: case ADDR_1632: case ADDR_1664: DESCRIPTOR64 Desc;
if (Addr->seg != g_LastSelector) { if (g_Target->GetSelDescriptor(g_Thread, g_Machine, Addr->seg, &Desc) == S_OK) { g_LastSelector = Addr->seg; g_LastBaseOffset = Desc.Base; } else { g_LastSelector = -1; g_LastBaseOffset = 0; } } Addr->off = Flat(*Addr) - g_LastBaseOffset; break;
case ADDR_FLAT: Addr->off = Flat(*Addr); break;
default: return; } }
void ComputeFlatAddress(PADDR Addr, PDESCRIPTOR64 Desc) { if (Addr->type & FLAT_COMPUTED) { return; }
switch(Addr->type & (~INSTR_POINTER)) { case ADDR_V86 | FLAT_BASIS: Flat(*Addr) = Addr->off; // Segment isn't actually used.
Addr->seg = 0; Addr->off = Flat(*Addr) & 0xffff; break; case ADDR_V86: Addr->off &= 0xffff; Flat(*Addr) = ((ULONG64)Addr->seg << 4) + Addr->off; break;
case ADDR_16: Addr->off &= 0xffff;
case ADDR_1632: case ADDR_1664: DESCRIPTOR64 DescBuf; ULONG64 Base;
if (Desc != NULL) { Base = Desc->Base; } else { if (Addr->seg != g_LastSelector) { if (g_Target->GetSelDescriptor(g_Thread, g_Machine, Addr->seg, &DescBuf) == S_OK) { g_LastSelector = Addr->seg; g_LastBaseOffset = DescBuf.Base; } else { g_LastSelector = -1; g_LastBaseOffset = 0; } }
Base = g_LastBaseOffset; } if ((Addr->type & (~INSTR_POINTER)) != ADDR_1664) { Flat(*Addr) = EXTEND64((ULONG)Addr->off + (ULONG)Base); } else { Flat(*Addr) = Addr->off + Base; } break;
case ADDR_FLAT: Flat(*Addr) = Addr->off; break;
default: return; }
Addr->type |= FLAT_COMPUTED; }
PADDR AddrAdd(PADDR Addr, ULONG64 Scalar) { if (fnotFlat(*Addr)) { ComputeFlatAddress(Addr, NULL); }
Flat(*Addr) += Scalar; Addr->off += Scalar; switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER))) { case ADDR_V86: Addr->off = Flat(*Addr) - EXTEND64((ULONG64)Addr->seg << 4); case ADDR_V86 | FLAT_BASIS: if (Addr->off > 0xffff) { ULONG64 excess = 1 + ((Addr->off - 0x10000) >> 4); Addr->seg += (USHORT)excess; Addr->off -= excess << 4; } break;
case ADDR_16: if (Addr->off > 0xffff) { Flat(*Addr) -= Addr->off & ~0xffff; Addr->off &= 0xffff; } break; case ADDR_1632: if (Addr->off > 0xffffffff) { Flat(*Addr) -= Addr->off & ~0xffffffff; Addr->off &= 0xffffffff; } break; } return Addr; }
PADDR AddrSub(PADDR Addr, ULONG64 Scalar) { if (fnotFlat(*Addr)) { ComputeFlatAddress(Addr, NULL); }
Flat(*Addr) -= Scalar; Addr->off -= Scalar;
switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER))) { case ADDR_V86: Addr->off = Flat(*Addr) - EXTEND64((ULONG64)Addr->seg << 4); case ADDR_V86 | FLAT_BASIS: if (Addr->off > 0xffff) { ULONG64 excess = 1 + ((0xffffffffffffffffUI64 - Addr->off) >> 4); Addr->seg -= (USHORT)excess; Addr->off += excess << 4; } break;
case ADDR_16: if (Addr->off > 0xffff) { Flat(*Addr) -= Addr->off & ~0xffff; Addr->off &= 0xffff; } break; case ADDR_1632: if (Addr->off > 0xffffffff) { Flat(*Addr) -= Addr->off & ~0xffffffff; Addr->off &= 0xffffffff; } break; } return Addr; }
|