Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
6.1 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // General ADDR routines.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. SHORT g_LastSelector = -1;
  10. ULONG64 g_LastBaseOffset;
  11. void
  12. dprintAddr(
  13. PADDR paddr
  14. )
  15. {
  16. switch (paddr->type & (~(FLAT_COMPUTED | INSTR_POINTER)))
  17. {
  18. case ADDR_V86:
  19. case ADDR_16:
  20. dprintf("%04x:%04x ", paddr->seg, (USHORT)paddr->off);
  21. break;
  22. case ADDR_1632:
  23. dprintf("%04x:%08lx ", paddr->seg, (ULONG)paddr->off);
  24. break;
  25. case ADDR_1664:
  26. dprintf("%04x:%s ", paddr->seg, FormatAddr64(paddr->off));
  27. break;
  28. case ADDR_FLAT:
  29. dprintf("%s ", FormatAddr64(paddr->off));
  30. break;
  31. }
  32. }
  33. void
  34. sprintAddr(
  35. PSTR *buffer,
  36. PADDR paddr
  37. )
  38. {
  39. switch (paddr->type & (~(FLAT_COMPUTED | INSTR_POINTER)))
  40. {
  41. case ADDR_V86:
  42. case ADDR_16:
  43. sprintf(*buffer,"%04x:%04x ", paddr->seg, (USHORT)paddr->off);
  44. break;
  45. case ADDR_1632:
  46. sprintf(*buffer,"%04x:%08lx ", paddr->seg, (ULONG)paddr->off);
  47. break;
  48. case ADDR_1664:
  49. sprintf(*buffer,"%04x:%s ",
  50. paddr->seg, FormatAddr64(paddr->off));
  51. break;
  52. case ADDR_FLAT:
  53. sprintf(*buffer,"%s ", FormatAddr64(paddr->off));
  54. break;
  55. }
  56. while (**buffer)
  57. {
  58. (*buffer)++;
  59. }
  60. }
  61. void
  62. MaskOutAddr(ULONG Mask, PADDR Addr)
  63. {
  64. switch(Addr->type & (~(FLAT_COMPUTED | INSTR_POINTER)))
  65. {
  66. case ADDR_V86:
  67. case ADDR_16:
  68. MaskOut(Mask, "%04x:%04x ", Addr->seg, (USHORT)Addr->off);
  69. break;
  70. case ADDR_1632:
  71. MaskOut(Mask, "%04x:%08lx ", Addr->seg, (ULONG)Addr->off);
  72. break;
  73. case ADDR_1664:
  74. MaskOut(Mask, "%04x:%s ", Addr->seg, FormatAddr64(Addr->off));
  75. break;
  76. case ADDR_FLAT:
  77. MaskOut(Mask, "%s ", FormatAddr64(Addr->off));
  78. break;
  79. }
  80. }
  81. void
  82. ComputeNativeAddress (
  83. PADDR paddr
  84. )
  85. {
  86. switch (paddr->type & (~(FLAT_COMPUTED | INSTR_POINTER)))
  87. {
  88. case ADDR_V86:
  89. paddr->off = Flat(*paddr) - ((ULONG)paddr->seg << 4);
  90. if (paddr->off > 0xffff)
  91. {
  92. ULONG64 excess = 1 + ((paddr->off - 0xffffL) >> 4);
  93. paddr->seg += (USHORT)excess;
  94. paddr->off -= excess << 4;
  95. }
  96. break;
  97. case ADDR_16:
  98. case ADDR_1632:
  99. case ADDR_1664:
  100. DESCRIPTOR64 desc;
  101. if (paddr->seg != g_LastSelector)
  102. {
  103. g_LastSelector = paddr->seg;
  104. g_Target->GetSelDescriptor
  105. (g_Machine, g_CurrentProcess->CurrentThread->Handle,
  106. paddr->seg, &desc);
  107. g_LastBaseOffset = desc.Base;
  108. }
  109. paddr->off = Flat(*paddr) - g_LastBaseOffset;
  110. break;
  111. case ADDR_FLAT:
  112. paddr->off = Flat(*paddr);
  113. break;
  114. default:
  115. return;
  116. }
  117. }
  118. void
  119. ComputeFlatAddress (
  120. PADDR paddr,
  121. PDESCRIPTOR64 pdesc
  122. )
  123. {
  124. if (paddr->type & FLAT_COMPUTED)
  125. {
  126. return;
  127. }
  128. switch (paddr->type & (~INSTR_POINTER))
  129. {
  130. case ADDR_V86:
  131. paddr->off &= 0xffff;
  132. Flat(*paddr) = ((ULONG)paddr->seg << 4) + paddr->off;
  133. break;
  134. case ADDR_16:
  135. paddr->off &= 0xffff;
  136. case ADDR_1632:
  137. case ADDR_1664:
  138. DESCRIPTOR64 desc;
  139. ULONG64 Base;
  140. if (pdesc != NULL)
  141. {
  142. Base = pdesc->Base;
  143. }
  144. else
  145. {
  146. if (paddr->seg != g_LastSelector)
  147. {
  148. g_LastSelector = paddr->seg;
  149. g_Target->GetSelDescriptor
  150. (g_Machine, g_CurrentProcess->CurrentThread->Handle,
  151. paddr->seg, pdesc = &desc);
  152. g_LastBaseOffset = pdesc->Base;
  153. }
  154. Base = g_LastBaseOffset;
  155. }
  156. if ((paddr->type & (~INSTR_POINTER)) != ADDR_1664)
  157. {
  158. Flat(*paddr) = EXTEND64((ULONG)paddr->off + (ULONG)Base);
  159. }
  160. else
  161. {
  162. Flat(*paddr) = paddr->off + Base;
  163. }
  164. break;
  165. case ADDR_FLAT:
  166. Flat(*paddr) = paddr->off;
  167. break;
  168. default:
  169. return;
  170. }
  171. paddr->type |= FLAT_COMPUTED;
  172. }
  173. PADDR
  174. AddrAdd(
  175. PADDR paddr,
  176. ULONG64 scalar
  177. )
  178. {
  179. if (fnotFlat(*paddr))
  180. {
  181. ComputeFlatAddress(paddr, NULL);
  182. }
  183. Flat(*paddr) += scalar;
  184. paddr->off += scalar;
  185. switch (paddr->type & (~(FLAT_COMPUTED | INSTR_POINTER)))
  186. {
  187. case ADDR_V86:
  188. paddr->off = Flat(*paddr) - EXTEND64((ULONG)paddr->seg << 4);
  189. if (paddr->off > 0xffff)
  190. {
  191. ULONG64 excess = 1 + ((paddr->off - 0x10000) >> 4);
  192. paddr->seg += (USHORT)excess;
  193. paddr->off -= excess << 4;
  194. }
  195. break;
  196. case ADDR_16:
  197. if (paddr->off > 0xffff)
  198. {
  199. Flat(*paddr) -= paddr->off & ~0xffff;
  200. paddr->off &= 0xffff;
  201. }
  202. break;
  203. case ADDR_1632:
  204. if (paddr->off > 0xffffffff)
  205. {
  206. Flat(*paddr) -= paddr->off & ~0xffffffff;
  207. paddr->off &= 0xffffffff;
  208. }
  209. break;
  210. }
  211. return paddr;
  212. }
  213. PADDR
  214. AddrSub(
  215. PADDR paddr,
  216. ULONG64 scalar
  217. )
  218. {
  219. if (fnotFlat(*paddr))
  220. {
  221. ComputeFlatAddress(paddr, NULL);
  222. }
  223. Flat(*paddr) -= scalar;
  224. paddr->off -= scalar;
  225. switch (paddr->type & (~(FLAT_COMPUTED | INSTR_POINTER)))
  226. {
  227. case ADDR_V86:
  228. paddr->off = Flat(*paddr) - EXTEND64((ULONG)paddr->seg << 4);
  229. if (paddr->off > 0xffff)
  230. {
  231. ULONG64 excess = 1 + ((0xffffffffffffffffUI64 - paddr->off) >> 4);
  232. paddr->seg -= (USHORT)excess;
  233. paddr->off += excess << 4;
  234. }
  235. break;
  236. case ADDR_16:
  237. if (paddr->off > 0xffff)
  238. {
  239. Flat(*paddr) -= paddr->off & ~0xffff;
  240. paddr->off &= 0xffff;
  241. }
  242. break;
  243. case ADDR_1632:
  244. if (paddr->off > 0xffffffff)
  245. {
  246. Flat(*paddr) -= paddr->off & ~0xffffffff;
  247. paddr->off &= 0xffffffff;
  248. }
  249. break;
  250. }
  251. return paddr;
  252. }