Leaked source code of windows server 2003
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.

304 lines
7.3 KiB

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