dbgapi.c 82 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. dbgapi.c
  5. Abstract:
  6. This module implements support for low level debugger core services.
  7. Author:
  8. Evan Green 7-May-2013
  9. Environment:
  10. Debug client
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "dbgrtl.h"
  16. #include <minoca/debug/spproto.h>
  17. #include <minoca/lib/im.h>
  18. #include <minoca/debug/dbgext.h>
  19. #include "dbgapi.h"
  20. #include "dbgrprof.h"
  21. #include "console.h"
  22. #include "userdbg.h"
  23. #include "symbols.h"
  24. #include "dbgrcomm.h"
  25. #include "dbgsym.h"
  26. #include <assert.h>
  27. #include <ctype.h>
  28. #include <errno.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. //
  33. // ---------------------------------------------------------------- Definitions
  34. //
  35. //
  36. // Define the number of milliseconds to poll and see if the user has requested
  37. // a break-in.
  38. //
  39. #define DEBUG_USER_POLL_MILLISECONDS 200
  40. //
  41. // Define the length of the standard x86 function prologue.
  42. //
  43. #define X86_FUNCTION_PROLOGUE_LENGTH 3
  44. //
  45. // ------------------------------------------------------ Data Type Definitions
  46. //
  47. typedef struct _DEBUG_COMPLETE_ACKNOWLEDGE_PACKET {
  48. DEBUG_PACKET_HEADER Header;
  49. DEBUG_PACKET_ACKNOWLEDGE Acknowledge;
  50. } DEBUG_COMPLETE_ACKNOWLEDGE_PACKET, *_DEBUG_COMPLETE_ACKNOWLEDGE_PACKET;
  51. //
  52. // ----------------------------------------------- Internal Function Prototypes
  53. //
  54. BOOL
  55. DbgpKdContinue (
  56. VOID
  57. );
  58. BOOL
  59. DbgpKdSetRegisters (
  60. PREGISTERS_UNION Registers
  61. );
  62. BOOL
  63. DbgpKdGetSpecialRegisters (
  64. PSPECIAL_REGISTERS_UNION SpecialRegisters
  65. );
  66. BOOL
  67. DbgpKdSetSpecialRegisters (
  68. PSET_SPECIAL_REGISTERS Command
  69. );
  70. BOOL
  71. DbgpKdSingleStep (
  72. VOID
  73. );
  74. BOOL
  75. DbgpKdWaitForEvent (
  76. PDEBUGGER_EVENT Event
  77. );
  78. BOOL
  79. DbgpKdRangeStep (
  80. PRANGE_STEP RangeStep
  81. );
  82. BOOL
  83. DbgpKdSwitchProcessors (
  84. ULONG ProcessorNumber
  85. );
  86. BOOL
  87. DbgpKdGetLoadedModuleList (
  88. PMODULE_LIST_HEADER *ModuleList
  89. );
  90. BOOL
  91. DbgpKdReadWriteMemory (
  92. BOOL WriteOperation,
  93. BOOL VirtualMemory,
  94. ULONGLONG Address,
  95. PVOID Buffer,
  96. ULONG BufferSize,
  97. PULONG BytesCompleted
  98. );
  99. BOOL
  100. DbgpKdReboot (
  101. DEBUG_REBOOT_TYPE RebootType
  102. );
  103. BOOL
  104. DbgpKdSendPacket (
  105. PDEBUG_PACKET Packet
  106. );
  107. BOOL
  108. DbgpKdReceivePacket (
  109. PDEBUG_PACKET Packet,
  110. ULONG TimeoutMilliseconds,
  111. PBOOL TimeoutOccurred
  112. );
  113. BOOL
  114. DbgpKdReceivePacketHeader (
  115. PDEBUG_PACKET_HEADER Packet,
  116. ULONG TimeoutMilliseconds,
  117. PBOOL TimeoutOccurred
  118. );
  119. INT
  120. DbgpKdSynchronize (
  121. VOID
  122. );
  123. USHORT
  124. DbgpKdCalculateChecksum (
  125. PVOID Data,
  126. ULONG DataLength
  127. );
  128. BOOL
  129. DbgpKdReceiveBytes (
  130. PVOID Buffer,
  131. ULONG BytesToRead
  132. );
  133. BOOL
  134. DbgpKdSendBytes (
  135. PVOID Buffer,
  136. ULONG BytesToSend
  137. );
  138. //
  139. // -------------------------------------------------------------------- Globals
  140. //
  141. BOOL DbgBreakInDesired;
  142. BOOL DbgBreakInRequestSent;
  143. //
  144. // Define the globals used to transmit and receive kernel debug packets.
  145. //
  146. DEBUG_PACKET DbgRxPacket;
  147. DEBUG_PACKET DbgTxPacket;
  148. //
  149. // Define what the function prologue might look like.
  150. //
  151. UCHAR DbgX86FunctionPrologue[X86_FUNCTION_PROLOGUE_LENGTH] = {0x55, 0x89, 0xE5};
  152. //
  153. // Set this to TRUE to view the bytes going across the wire.
  154. //
  155. BOOL DbgKdPrintRawBytes = FALSE;
  156. BOOL DbgKdPrintMemoryAccesses = FALSE;
  157. //
  158. // Set this to TRUE to enable byte escaping for transports that cannot send
  159. // certain bytes.
  160. //
  161. BOOL DbgKdEncodeBytes = FALSE;
  162. //
  163. // This boolean gets set to TRUE when a resynchronization byte is found in the
  164. // data stream between packets.
  165. //
  166. BOOL DbgKdConnectionReset;
  167. //
  168. // ------------------------------------------------------------------ Functions
  169. //
  170. INT
  171. DbgInitialize (
  172. PDEBUGGER_CONTEXT Context,
  173. DEBUG_CONNECTION_TYPE ConnectionType
  174. )
  175. /*++
  176. Routine Description:
  177. This routine initializes data structures for common debugger API.
  178. Arguments:
  179. Context - Supplies a pointer to the application context.
  180. ConnectionType - Supplies the type of debug connection to set the debugger
  181. up in.
  182. Return Value:
  183. 0 on success.
  184. Returns an error code on failure.
  185. --*/
  186. {
  187. assert(ConnectionType != DebugConnectionInvalid);
  188. Context->ConnectionType = ConnectionType;
  189. if (ConnectionType == DebugConnectionUser) {
  190. Context->MachineType = DbgGetHostMachineType();
  191. }
  192. return 0;
  193. }
  194. VOID
  195. DbgDestroy (
  196. PDEBUGGER_CONTEXT Context,
  197. DEBUG_CONNECTION_TYPE ConnectionType
  198. )
  199. /*++
  200. Routine Description:
  201. This routine destroys data structures for common debugger API.
  202. Arguments:
  203. Context - Supplies a pointer to the application context.
  204. ConnectionType - Supplies the type of debug connection for which the
  205. debugger was initialized.
  206. Return Value:
  207. None.
  208. --*/
  209. {
  210. return;
  211. }
  212. INT
  213. DbgKdConnect (
  214. PDEBUGGER_CONTEXT Context,
  215. BOOL RequestBreak,
  216. PCONNECTION_RESPONSE *ConnectionDetails,
  217. PULONG BufferSize
  218. )
  219. /*++
  220. Routine Description:
  221. This routine establishes a link with the target. It is assumed that
  222. the underlying communication layer has already been established (COM ports
  223. have been opened and initialized, etc).
  224. Arguments:
  225. Context - Supplies a pointer to the application context.
  226. RequestBreak - Supplies a boolean indicating whether or not the host
  227. should break in.
  228. ConnectionDetails - Supplies a pointer where a pointer to details about the
  229. kernel connection will be returned. The caller is responsible for
  230. freeing this memory when done.
  231. BufferSize - Supplies a pointer where the total size of the connection
  232. details buffer will be returned.
  233. Return Value:
  234. 0 on success.
  235. Non-zero on error.
  236. --*/
  237. {
  238. PCONNECTION_REQUEST ConnectionRequest;
  239. PCONNECTION_RESPONSE ConnectionResponse;
  240. PCONNECTION_RESPONSE NewResponse;
  241. INT Result;
  242. *BufferSize = 0;
  243. *ConnectionDetails = NULL;
  244. assert(Context->ConnectionType == DebugConnectionKernel);
  245. //
  246. // Set the connection reset flag so that receive knows to ignore incoming
  247. // resync bytes.
  248. //
  249. DbgKdConnectionReset = TRUE;
  250. //
  251. // Synchronize with the target to make sure it is ready and listening.
  252. //
  253. Result = DbgpKdSynchronize();
  254. if (Result != 0) {
  255. return Result;
  256. }
  257. //
  258. // Fill out the connection request structure, and send the initial packet.
  259. //
  260. ConnectionRequest = (PCONNECTION_REQUEST)DbgTxPacket.Payload;
  261. ConnectionRequest->ProtocolMajorVersion = DEBUG_PROTOCOL_MAJOR_VERSION;
  262. ConnectionRequest->ProtocolRevision = DEBUG_PROTOCOL_REVISION;
  263. ConnectionRequest->BreakRequested = RequestBreak;
  264. DbgTxPacket.Header.Command = DbgConnectionRequest;
  265. DbgTxPacket.Header.PayloadSize = sizeof(CONNECTION_REQUEST);
  266. Result = DbgpKdSendPacket(&DbgTxPacket);
  267. if (Result == FALSE) {
  268. DbgOut("Unable to send Connection Request packet!\n");
  269. return EPIPE;
  270. }
  271. //
  272. // Attempt to receive the connection response packet. Get through resync
  273. // bytes.
  274. //
  275. Result = DbgpKdReceivePacket(&DbgRxPacket, 0, NULL);
  276. if (Result == FALSE) {
  277. DbgOut("Unable to receive Connection Response packet!\n");
  278. return EPIPE;
  279. }
  280. //
  281. // The connection is now established, so future resync bytes reset it.
  282. //
  283. DbgKdConnectionReset = FALSE;
  284. ConnectionResponse = (PCONNECTION_RESPONSE)DbgRxPacket.Payload;
  285. if (DbgRxPacket.Header.Command != DbgConnectionAcknowledge) {
  286. //
  287. // Check for a debugger/target version mismatch, and bail out if one
  288. // occurred.
  289. //
  290. if (DbgRxPacket.Header.Command == DbgConnectionWrongVersion) {
  291. DbgOut("Version mismatch! Debugger version: %d.%02d, Target "
  292. "version: %d.%02d.\n",
  293. DEBUG_PROTOCOL_MAJOR_VERSION,
  294. DEBUG_PROTOCOL_REVISION,
  295. ConnectionResponse->ProtocolMajorVersion,
  296. ConnectionResponse->ProtocolRevision);
  297. //
  298. // Check if the target rejected the request gracefully.
  299. //
  300. } else if (DbgRxPacket.Header.Command == DbgConnectionInvalidRequest) {
  301. DbgOut("Command rejected by target\n");
  302. //
  303. // The target sent something completely unexpected.
  304. //
  305. } else {
  306. DbgOut("Expecting DbgConnectionAcknowledge, got %d\n",
  307. DbgRxPacket.Header.Command);
  308. }
  309. return EIO;
  310. }
  311. NewResponse = malloc(DbgRxPacket.Header.PayloadSize);
  312. if (NewResponse == NULL) {
  313. return ENOMEM;
  314. }
  315. //
  316. // A connection was successfully established. Copy the connection details
  317. // to the caller's structure.
  318. //
  319. RtlCopyMemory(NewResponse,
  320. ConnectionResponse,
  321. DbgRxPacket.Header.PayloadSize);
  322. *ConnectionDetails = NewResponse;
  323. *BufferSize = DbgRxPacket.Header.PayloadSize;
  324. return 0;
  325. }
  326. INT
  327. DbgContinue (
  328. PDEBUGGER_CONTEXT Context,
  329. ULONG SignalToDeliver
  330. )
  331. /*++
  332. Routine Description:
  333. This routine sends the "go" command to the target, signaling to continue
  334. execution.
  335. Arguments:
  336. Context - Supplies a pointer to the application context.
  337. SignalToDeliver - Supplies the signal number to actually send to the
  338. application. For kernel debugging, this parameter is ignored.
  339. Return Value:
  340. 0 on success.
  341. Non-zero on failure.
  342. --*/
  343. {
  344. INT Result;
  345. if (Context->ConnectionType == DebugConnectionKernel) {
  346. Result = DbgpKdContinue();
  347. } else if (Context->ConnectionType == DebugConnectionUser) {
  348. Result = DbgpUserContinue(SignalToDeliver);
  349. } else {
  350. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  351. Result = FALSE;
  352. }
  353. if (Result != FALSE) {
  354. Context->TargetFlags |= DEBUGGER_TARGET_RUNNING;
  355. Result = 0;
  356. } else {
  357. Result = EINVAL;
  358. }
  359. return Result;
  360. }
  361. ULONG
  362. DbgGetSignalToDeliver (
  363. PDEBUGGER_CONTEXT Context
  364. )
  365. /*++
  366. Routine Description:
  367. This routine returns the value for the "signal to deliver" parameters when
  368. letting the target continue. For user mode processes, breaks into the
  369. debugger occur because of signal delivery, and the debugger has the choice
  370. of whether or not to actually deliver a signal.
  371. Arguments:
  372. Context - Supplies a pointer to the application context.
  373. Return Value:
  374. Returns the signal to deliver for the upcoming target continuation.
  375. 0 for kernel debugging or if no signal should be delivered to the target.
  376. This value can just be passed through.
  377. --*/
  378. {
  379. ULONG SignalToDeliver;
  380. SignalToDeliver = 0;
  381. if (Context->ConnectionType == DebugConnectionUser) {
  382. SignalToDeliver = Context->CurrentEvent.SignalParameters.SignalNumber;
  383. SignalToDeliver = DbgpUserGetSignalToDeliver(SignalToDeliver);
  384. }
  385. return SignalToDeliver;
  386. }
  387. INT
  388. DbgSetRegisters (
  389. PDEBUGGER_CONTEXT Context,
  390. PREGISTERS_UNION Registers
  391. )
  392. /*++
  393. Routine Description:
  394. This routine sets the registers of the target.
  395. Arguments:
  396. Context - Supplies a pointer to the application context.
  397. Registers - Supplies a pointer to the registers to set. All register values
  398. will be written.
  399. Return Value:
  400. 0 on success.
  401. Non-zero on failure.
  402. --*/
  403. {
  404. INT Result;
  405. if (Context->ConnectionType == DebugConnectionKernel) {
  406. Result = DbgpKdSetRegisters(Registers);
  407. } else if (Context->ConnectionType == DebugConnectionUser) {
  408. Result = DbgpUserSetRegisters(Registers);
  409. } else {
  410. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  411. Result = FALSE;
  412. }
  413. if (Result != FALSE) {
  414. Result = 0;
  415. } else {
  416. Result = EINVAL;
  417. }
  418. return Result;
  419. }
  420. INT
  421. DbgGetSpecialRegisters (
  422. PDEBUGGER_CONTEXT Context,
  423. PSPECIAL_REGISTERS_UNION SpecialRegisters
  424. )
  425. /*++
  426. Routine Description:
  427. This routine gets the registers of the target.
  428. Arguments:
  429. Context - Supplies a pointer to the application context.
  430. SpecialRegisters - Supplies a pointer where the registers will be returned.
  431. Return Value:
  432. 0 on success.
  433. Non-zero on failure.
  434. --*/
  435. {
  436. INT Result;
  437. if (Context->ConnectionType == DebugConnectionKernel) {
  438. Result = DbgpKdGetSpecialRegisters(SpecialRegisters);
  439. } else if (Context->ConnectionType == DebugConnectionUser) {
  440. DbgOut("Special registers cannot be accessed in user mode.\n");
  441. Result = FALSE;
  442. } else {
  443. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  444. Result = FALSE;
  445. }
  446. if (Result != FALSE) {
  447. Result = 0;
  448. } else {
  449. Result = EINVAL;
  450. }
  451. return Result;
  452. }
  453. INT
  454. DbgSetSpecialRegisters (
  455. PDEBUGGER_CONTEXT Context,
  456. PSET_SPECIAL_REGISTERS Command
  457. )
  458. /*++
  459. Routine Description:
  460. This routine sets the special registers from the target.
  461. Arguments:
  462. Context - Supplies a pointer to the application context.
  463. Command - Supplies a pointer to the details of the set special registers
  464. command.
  465. Return Value:
  466. 0 on success.
  467. Non-zero on failure.
  468. --*/
  469. {
  470. INT Result;
  471. if (Context->ConnectionType == DebugConnectionKernel) {
  472. Result = DbgpKdSetSpecialRegisters(Command);
  473. } else if (Context->ConnectionType == DebugConnectionUser) {
  474. DbgOut("Special registers cannot be accessed in user mode.\n");
  475. Result = FALSE;
  476. } else {
  477. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  478. Result = FALSE;
  479. }
  480. if (Result != FALSE) {
  481. Result = 0;
  482. } else {
  483. Result = EINVAL;
  484. }
  485. return Result;
  486. }
  487. INT
  488. DbgSingleStep (
  489. PDEBUGGER_CONTEXT Context,
  490. ULONG SignalToDeliver
  491. )
  492. /*++
  493. Routine Description:
  494. This routine steps the target by one instruction.
  495. Arguments:
  496. Context - Supplies a pointer to the application context.
  497. SignalToDeliver - Supplies the signal number to actually send to the
  498. application. For kernel debugging, this parameter is ignored.
  499. Return Value:
  500. 0 on success.
  501. Returns an error code on failure.
  502. --*/
  503. {
  504. INT Result;
  505. if (Context->ConnectionType == DebugConnectionKernel) {
  506. Result = DbgpKdSingleStep();
  507. } else if (Context->ConnectionType == DebugConnectionUser) {
  508. Result = DbgpUserSingleStep(SignalToDeliver);
  509. } else {
  510. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  511. Result = FALSE;
  512. }
  513. if (Result == FALSE) {
  514. return EINVAL;
  515. }
  516. Context->TargetFlags |= DEBUGGER_TARGET_RUNNING;
  517. Result = 0;
  518. return Result;
  519. }
  520. INT
  521. DbgWaitForEvent (
  522. PDEBUGGER_CONTEXT Context
  523. )
  524. /*++
  525. Routine Description:
  526. This routine gets an event from the target, such as a break event or other
  527. exception.
  528. Arguments:
  529. Context - Supplies a pointer to the application context.
  530. Return Value:
  531. 0 on success.
  532. Non-zero on failure.
  533. --*/
  534. {
  535. INT Result;
  536. Context->CurrentEvent.Type = DebuggerEventInvalid;
  537. if (Context->ConnectionType == DebugConnectionKernel) {
  538. Result = DbgpKdWaitForEvent(&(Context->CurrentEvent));
  539. } else if (Context->ConnectionType == DebugConnectionUser) {
  540. Result = DbgpUserWaitForEvent(&(Context->CurrentEvent));
  541. } else {
  542. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  543. Result = FALSE;
  544. }
  545. if (Result != FALSE) {
  546. Result = 0;
  547. } else {
  548. Result = EINVAL;
  549. }
  550. return Result;
  551. }
  552. INT
  553. DbgRangeStep (
  554. PDEBUGGER_CONTEXT Context,
  555. PRANGE_STEP RangeStep,
  556. ULONG SignalToDeliver
  557. )
  558. /*++
  559. Routine Description:
  560. This routine continues execution until a range of execution addresses is
  561. reached.
  562. Arguments:
  563. Context - Supplies the application context.
  564. RangeStep - Supplies a pointer to the range to go to.
  565. SignalToDeliver - Supplies the signal number to actually send to the
  566. application. For kernel debugging, this parameter is ignored.
  567. Return Value:
  568. 0 on success.
  569. Returns an error code on failure.
  570. --*/
  571. {
  572. INT Result;
  573. if (Context->ConnectionType == DebugConnectionKernel) {
  574. Result = DbgpKdRangeStep(RangeStep);
  575. } else if (Context->ConnectionType == DebugConnectionUser) {
  576. Result = DbgpUserRangeStep(RangeStep, SignalToDeliver);
  577. } else {
  578. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  579. Result = FALSE;
  580. }
  581. if (Result == FALSE) {
  582. return EINVAL;
  583. }
  584. Result = 0;
  585. Context->TargetFlags |= DEBUGGER_TARGET_RUNNING;
  586. return Result;
  587. }
  588. INT
  589. DbgSwitchProcessors (
  590. PDEBUGGER_CONTEXT Context,
  591. ULONG ProcessorNumber
  592. )
  593. /*++
  594. Routine Description:
  595. This routine switches the debugger to another processor.
  596. Arguments:
  597. Context - Supplies a pointer to the debugger context.
  598. ProcessorNumber - Supplies the processor number to switch to.
  599. DebuggeeRunning - Supplies a pointer where a boolean will be returned
  600. indicating whether or not the target has continued.
  601. Return Value:
  602. 0 on success.
  603. Returns an error code on failure.
  604. --*/
  605. {
  606. INT Result;
  607. if (Context->ConnectionType == DebugConnectionKernel) {
  608. Result = DbgpKdSwitchProcessors(ProcessorNumber);
  609. if (Result == FALSE) {
  610. Result = EINVAL;
  611. goto SwitchProcessorsEnd;
  612. } else {
  613. Context->TargetFlags |= DEBUGGER_TARGET_RUNNING;
  614. }
  615. } else if (Context->ConnectionType == DebugConnectionUser) {
  616. Result = DbgpUserSwitchThread(ProcessorNumber,
  617. &(Context->CurrentEvent));
  618. if (Result == FALSE) {
  619. Result = EINVAL;
  620. goto SwitchProcessorsEnd;
  621. }
  622. } else {
  623. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  624. Result = EINVAL;
  625. goto SwitchProcessorsEnd;
  626. }
  627. Result = 0;
  628. SwitchProcessorsEnd:
  629. return Result;
  630. }
  631. INT
  632. DbgGetThreadList (
  633. PDEBUGGER_CONTEXT Context,
  634. PULONG ThreadCount,
  635. PULONG *ThreadIds
  636. )
  637. /*++
  638. Routine Description:
  639. This routine gets the list of active threads in the process (or active
  640. processors in the machine for kernel mode).
  641. Arguments:
  642. Context - Supplies a pointer to the application context.
  643. ThreadCount - Supplies a pointer where the number of threads will be
  644. returned on success.
  645. ThreadIds - Supplies a pointer where an array of thread IDs (or processor
  646. numbers) will be returned on success. It is the caller's responsibility
  647. to free this memory.
  648. Return Value:
  649. 0 on success.
  650. Non-zero on failure.
  651. --*/
  652. {
  653. ULONG AllocationSize;
  654. PULONG CurrentThreadEntry;
  655. ULONG ProcessorCount;
  656. PULONG Processors;
  657. INT Result;
  658. ULONG ThreadIndex;
  659. *ThreadCount = 0;
  660. *ThreadIds = NULL;
  661. if (Context->ConnectionType == DebugConnectionKernel) {
  662. ProcessorCount =
  663. Context->CurrentEvent.BreakNotification.ProcessorOrThreadCount;
  664. assert(ProcessorCount != 0);
  665. *ThreadCount = ProcessorCount;
  666. AllocationSize = sizeof(ULONG) * ProcessorCount;
  667. Processors = malloc(AllocationSize);
  668. if (Processors == NULL) {
  669. DbgOut("Error: Failed to malloc %d for processor list.\n",
  670. AllocationSize);
  671. return ENOMEM;
  672. }
  673. CurrentThreadEntry = Processors;
  674. for (ThreadIndex = 0; ThreadIndex < ProcessorCount; ThreadIndex += 1) {
  675. *CurrentThreadEntry = ThreadIndex;
  676. }
  677. *ThreadIds = Processors;
  678. Result = TRUE;
  679. } else if (Context->ConnectionType == DebugConnectionUser) {
  680. Result = DbgpUserGetThreadList(ThreadCount, ThreadIds);
  681. } else {
  682. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  683. Result = FALSE;
  684. }
  685. if (Result != FALSE) {
  686. Result = 0;
  687. } else {
  688. Result = EINVAL;
  689. }
  690. return Result;
  691. }
  692. INT
  693. DbgGetLoadedModuleList (
  694. PDEBUGGER_CONTEXT Context,
  695. PMODULE_LIST_HEADER *ModuleList
  696. )
  697. /*++
  698. Routine Description:
  699. This routine retrieves the list of loaded binaries from the target.
  700. Arguments:
  701. Context - Supplies a pointer to the application context.
  702. ModuleList - Supplies a pointer where a pointer to the loaded module header
  703. and subsequent array of entries will be returned. It is the caller's
  704. responsibility to free this allocated memory when finished.
  705. Return Value:
  706. 0 on success.
  707. Non-zero on failure.
  708. --*/
  709. {
  710. INT Result;
  711. if (Context->ConnectionType == DebugConnectionKernel) {
  712. Result = DbgpKdGetLoadedModuleList(ModuleList);
  713. } else if (Context->ConnectionType == DebugConnectionUser) {
  714. Result = DbgpUserGetLoadedModuleList(ModuleList);
  715. } else {
  716. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  717. Result = FALSE;
  718. }
  719. if (Result != FALSE) {
  720. Result = 0;
  721. } else {
  722. Result = EINVAL;
  723. }
  724. return Result;
  725. }
  726. VOID
  727. DbgRequestBreakIn (
  728. PDEBUGGER_CONTEXT Context
  729. )
  730. /*++
  731. Routine Description:
  732. This routine attempts to stop the running target.
  733. Arguments:
  734. Context - Supplies a pointer to the application context.
  735. Return Value:
  736. None.
  737. --*/
  738. {
  739. if (Context->ConnectionType == DebugConnectionKernel) {
  740. DbgBreakInRequestSent = FALSE;
  741. DbgBreakInDesired = TRUE;
  742. } else if (Context->ConnectionType == DebugConnectionUser) {
  743. DbgpUserRequestBreakIn();
  744. } else {
  745. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  746. }
  747. return;
  748. }
  749. INT
  750. DbgReadMemory (
  751. PDEBUGGER_CONTEXT Context,
  752. BOOL VirtualMemory,
  753. ULONGLONG Address,
  754. ULONG BytesToRead,
  755. PVOID Buffer,
  756. PULONG BytesRead
  757. )
  758. /*++
  759. Routine Description:
  760. This routine retrieves the debuggee's memory.
  761. Arguments:
  762. Context - Supplies a pointer to the application context.
  763. VirtualMemory - Supplies a flag indicating whether the read should be
  764. virtual or physical.
  765. Address - Supplies the address to read from the target's memory.
  766. BytesToRead - Supplies the number of bytes to be read.
  767. Buffer - Supplies a pointer to the buffer where the memory contents will be
  768. returned.
  769. BytesRead - Supplies a pointer that receive the number of bytes that were
  770. actually read from the target.
  771. Return Value:
  772. 0 on success.
  773. Returns an error code on failure.
  774. --*/
  775. {
  776. BOOL Result;
  777. if (Context->ConnectionType == DebugConnectionKernel) {
  778. Result = DbgpKdReadWriteMemory(FALSE,
  779. VirtualMemory,
  780. Address,
  781. Buffer,
  782. BytesToRead,
  783. BytesRead);
  784. } else if (Context->ConnectionType == DebugConnectionUser) {
  785. Result = DbgpUserReadWriteMemory(FALSE,
  786. VirtualMemory,
  787. Address,
  788. Buffer,
  789. BytesToRead,
  790. BytesRead);
  791. } else {
  792. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  793. Result = FALSE;
  794. }
  795. if (Result == FALSE) {
  796. return EINVAL;
  797. }
  798. return 0;
  799. }
  800. INT
  801. DbgWriteMemory (
  802. PDEBUGGER_CONTEXT Context,
  803. BOOL VirtualMemory,
  804. ULONGLONG Address,
  805. ULONG BytesToWrite,
  806. PVOID Buffer,
  807. PULONG BytesWritten
  808. )
  809. /*++
  810. Routine Description:
  811. This routine writes to the debuggee's memory.
  812. Arguments:
  813. Context - Supplies a pointer to the application context.
  814. VirtualMemory - Supplies a flag indicating whether the read should be
  815. virtual or physical.
  816. Address - Supplies the address to write to the target's memory.
  817. BytesToWrite - Supplies the number of bytes to be written.
  818. Buffer - Supplies a pointer to the buffer containing the values to write.
  819. BytesWritten - Supplies a pointer that receives the number of bytes that
  820. were actually written to the target.
  821. Return Value:
  822. 0 if the write was successful.
  823. Returns an error code on failure.
  824. --*/
  825. {
  826. INT Result;
  827. if (Context->ConnectionType == DebugConnectionKernel) {
  828. Result = DbgpKdReadWriteMemory(TRUE,
  829. VirtualMemory,
  830. Address,
  831. Buffer,
  832. BytesToWrite,
  833. BytesWritten);
  834. } else if (Context->ConnectionType == DebugConnectionUser) {
  835. Result = DbgpUserReadWriteMemory(TRUE,
  836. VirtualMemory,
  837. Address,
  838. Buffer,
  839. BytesToWrite,
  840. BytesWritten);
  841. } else {
  842. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  843. Result = FALSE;
  844. }
  845. if (Result == FALSE) {
  846. return EINVAL;
  847. }
  848. return 0;
  849. }
  850. INT
  851. DbgReboot (
  852. PDEBUGGER_CONTEXT Context,
  853. ULONG RebootType
  854. )
  855. /*++
  856. Routine Description:
  857. This routine attempts to reboot the target machine.
  858. Arguments:
  859. Context - Supplies a pointer to the application context.
  860. RebootType - Supplies the type of reboot to perform. See the
  861. DEBUG_REBOOT_TYPE enumeration.
  862. Return Value:
  863. 0 if the write was successful.
  864. Returns an error code on failure.
  865. --*/
  866. {
  867. INT Result;
  868. if (Context->ConnectionType == DebugConnectionKernel) {
  869. Result = DbgpKdReboot(RebootType);
  870. if (Result == FALSE) {
  871. Result = EINVAL;
  872. }
  873. Result = 0;
  874. } else if (Context->ConnectionType == DebugConnectionUser) {
  875. DbgOut("Reboot is only supported on kernel debug targets.\n");
  876. Result = ENODEV;
  877. } else {
  878. DbgOut("Error: Unknown connection type %d.\n", Context->ConnectionType);
  879. Result = EINVAL;
  880. }
  881. if (Result == 0) {
  882. Context->TargetFlags |= DEBUGGER_TARGET_RUNNING;
  883. }
  884. return Result;
  885. }
  886. INT
  887. DbgGetCallStack (
  888. PDEBUGGER_CONTEXT Context,
  889. PREGISTERS_UNION Registers,
  890. PSTACK_FRAME Frames,
  891. PULONG FrameCount
  892. )
  893. /*++
  894. Routine Description:
  895. This routine attempts to unwind the call stack starting at the given
  896. machine state.
  897. Arguments:
  898. Context - Supplies a pointer to the application context.
  899. Registers - Supplies an optional pointer to the registers on input. On
  900. output, these registers will be updated with the unwound value. If this
  901. is NULL, then the current break notification registers will be used.
  902. Frames - Supplies a pointer where the array of stack frames will be
  903. returned.
  904. FrameCount - Supplies the number of frames allocated in the frames
  905. argument, representing the maximum number of frames to get. On output,
  906. returns the number of valid frames in the array.
  907. Return Value:
  908. 0 on success.
  909. Returns an error code on failure.
  910. --*/
  911. {
  912. ULONG FrameIndex;
  913. REGISTERS_UNION LocalRegisters;
  914. INT SearchIndex;
  915. INT Status;
  916. BOOL Unwind;
  917. if (Registers == NULL) {
  918. assert(Context->CurrentEvent.Type == DebuggerEventBreak);
  919. RtlCopyMemory(&LocalRegisters,
  920. &(Context->CurrentEvent.BreakNotification.Registers),
  921. sizeof(REGISTERS_UNION));
  922. Registers = &LocalRegisters;
  923. }
  924. Unwind = TRUE;
  925. FrameIndex = 0;
  926. while (FrameIndex < *FrameCount) {
  927. Status = DbgStackUnwind(Context,
  928. Registers,
  929. &Unwind,
  930. &(Frames[FrameIndex]));
  931. if (Status == EOF) {
  932. Status = 0;
  933. break;
  934. } else if (Status != 0) {
  935. break;
  936. }
  937. //
  938. // If the stack frame appears to loop back on itself, stop.
  939. //
  940. for (SearchIndex = 0; SearchIndex < FrameIndex; SearchIndex += 1) {
  941. if (Frames[SearchIndex].FramePointer ==
  942. Frames[FrameIndex].FramePointer) {
  943. break;
  944. }
  945. }
  946. FrameIndex += 1;
  947. if (SearchIndex != FrameIndex - 1) {
  948. DbgOut("Stack frame loops, frame %I64x.\n",
  949. Frames[FrameIndex].FramePointer);
  950. break;
  951. }
  952. }
  953. *FrameCount = FrameIndex;
  954. return Status;
  955. }
  956. INT
  957. DbgStackUnwind (
  958. PDEBUGGER_CONTEXT Context,
  959. PREGISTERS_UNION Registers,
  960. PBOOL Unwind,
  961. PSTACK_FRAME Frame
  962. )
  963. /*++
  964. Routine Description:
  965. This routine attempts to unwind the stack by one frame.
  966. Arguments:
  967. Context - Supplies a pointer to the application context.
  968. Registers - Supplies a pointer to the registers on input. On output, these
  969. registers will be updated with the unwound value.
  970. Unwind - Supplies a pointer that on input should initially be set to TRUE,
  971. indicating to use the symbol unwinder if possible. If unwinding is not
  972. possible, this will be set to FALSE, and should remain FALSE for the
  973. remainder of the stack frames unwound.
  974. Frame - Supplies a pointer where the basic frame information for this
  975. frame will be returned.
  976. Return Value:
  977. 0 on success.
  978. EOF if there are no more stack frames.
  979. Returns an error code on failure.
  980. --*/
  981. {
  982. ULONGLONG BasePointer;
  983. ULONG ByteIndex;
  984. ULONG BytesRead;
  985. ULONGLONG DebasedPc;
  986. PDEBUGGER_MODULE Module;
  987. ULONGLONG Pc;
  988. ULONG PointerSize;
  989. ULONGLONG StackPointer;
  990. INT Status;
  991. PDEBUG_SYMBOLS Symbols;
  992. UCHAR WorkingBuffer[24];
  993. UCHAR X86InstructionContents[X86_FUNCTION_PROLOGUE_LENGTH];
  994. //
  995. // First look up the symbols and see if they can unwind the stack.
  996. //
  997. Pc = DbgGetPc(Context, Registers);
  998. if (*Unwind != FALSE) {
  999. Module = DbgpFindModuleFromAddress(Context, Pc, &DebasedPc);
  1000. if ((Module != NULL) && (Module->Symbols != NULL) &&
  1001. (Module->Symbols->Interface->Unwind != NULL)) {
  1002. Symbols = Module->Symbols;
  1003. assert(Symbols->RegistersContext == NULL);
  1004. Symbols->RegistersContext = Registers;
  1005. Status = Symbols->Interface->Unwind(Symbols, DebasedPc, Frame);
  1006. Symbols->RegistersContext = NULL;
  1007. if (Status != 0) {
  1008. if (Status != ENOENT) {
  1009. DbgOut("Failed to unwind stack at PC 0x%I64x\n", Pc);
  1010. }
  1011. } else {
  1012. //
  1013. // Set the PC to the return address. For architectures like
  1014. // x86 this is a no-op. On ARM, the return address register
  1015. // (r14) is different than the PC (r15).
  1016. //
  1017. DbgSetPc(Context, Registers, Frame->ReturnAddress);
  1018. goto StackUnwindEnd;
  1019. }
  1020. }
  1021. *Unwind = FALSE;
  1022. }
  1023. //
  1024. // Symbols do not exist or were no help. Use traditional frame chaining to
  1025. // unwind the stack.
  1026. //
  1027. PointerSize = DbgGetTargetPointerSize(Context);
  1028. DbgGetStackRegisters(Context, Registers, &StackPointer, &BasePointer);
  1029. switch (Context->MachineType) {
  1030. case MACHINE_TYPE_X86:
  1031. //
  1032. // If the instruction pointer was supplied, check the contents of the
  1033. // instruction against the standard prologue. If they're equal, then
  1034. // set up the first stack frame to more accurately represent the
  1035. // first stack frame that hasn't quite yet been created.
  1036. //
  1037. if (Pc != 0) {
  1038. Status = DbgReadMemory(Context,
  1039. TRUE,
  1040. Pc,
  1041. X86_FUNCTION_PROLOGUE_LENGTH,
  1042. X86InstructionContents,
  1043. &BytesRead);
  1044. if ((Status == 0) &&
  1045. (BytesRead == X86_FUNCTION_PROLOGUE_LENGTH)) {
  1046. for (ByteIndex = 0;
  1047. ByteIndex < X86_FUNCTION_PROLOGUE_LENGTH;
  1048. ByteIndex += 1) {
  1049. if (X86InstructionContents[ByteIndex] !=
  1050. DbgX86FunctionPrologue[ByteIndex]) {
  1051. break;
  1052. }
  1053. }
  1054. //
  1055. // If the for loop made it all the way through without breaking,
  1056. // a function prologue is about to execute. The base pointer is
  1057. // in the stack pointer, and is about to be pushed, so parse the
  1058. // first frame keeping that in mind. The return address was the
  1059. // most recent thing pushed on the stack.
  1060. //
  1061. if (ByteIndex == X86_FUNCTION_PROLOGUE_LENGTH) {
  1062. Frame->FramePointer = StackPointer + PointerSize;
  1063. Frame->ReturnAddress = 0;
  1064. Status = DbgReadMemory(Context,
  1065. TRUE,
  1066. StackPointer,
  1067. PointerSize,
  1068. &(Frame->ReturnAddress),
  1069. &BytesRead);
  1070. if ((Status != 0) || (BytesRead != PointerSize)) {
  1071. if (Status == 0) {
  1072. Status = EINVAL;
  1073. }
  1074. goto StackUnwindEnd;
  1075. }
  1076. }
  1077. }
  1078. }
  1079. //
  1080. // Stop if the base pointer is zero.
  1081. //
  1082. if (BasePointer == 0) {
  1083. Status = EOF;
  1084. goto StackUnwindEnd;
  1085. }
  1086. //
  1087. // Store the base pointer for the current frame.
  1088. //
  1089. Frame->FramePointer = BasePointer;
  1090. //
  1091. // From the base pointer, the next two pointers in memory are the
  1092. // next base pointer and then the return address.
  1093. //
  1094. Status = DbgReadMemory(Context,
  1095. TRUE,
  1096. BasePointer,
  1097. PointerSize * 2,
  1098. WorkingBuffer,
  1099. &BytesRead);
  1100. if ((Status != 0) || (BytesRead != (PointerSize * 2))) {
  1101. if (Status == 0) {
  1102. Status = EINVAL;
  1103. }
  1104. goto StackUnwindEnd;
  1105. }
  1106. BasePointer = 0;
  1107. RtlCopyMemory(&BasePointer, WorkingBuffer, PointerSize);
  1108. Frame->ReturnAddress = 0;
  1109. RtlCopyMemory(&(Frame->ReturnAddress),
  1110. (PUCHAR)WorkingBuffer + PointerSize,
  1111. PointerSize);
  1112. //
  1113. // Update the registers.
  1114. //
  1115. Registers->X86.Eip = Frame->ReturnAddress;
  1116. Registers->X86.Esp = Registers->X86.Ebp;
  1117. Registers->X86.Ebp = BasePointer;
  1118. break;
  1119. case MACHINE_TYPE_ARM:
  1120. //
  1121. // Stop if the base pointer is zero.
  1122. //
  1123. if (BasePointer == 0) {
  1124. Status = EOF;
  1125. goto StackUnwindEnd;
  1126. }
  1127. //
  1128. // The newer AAPCS calling convention sets up the frames where
  1129. // *(fp-4) is next frame pointer, and *fp is the return address.
  1130. // Store the base pointer for the current frame.
  1131. //
  1132. Frame->FramePointer = BasePointer;
  1133. Frame->ReturnAddress = 0;
  1134. //
  1135. // Read in just below the base of the frame to get the return
  1136. // address and next frame address.
  1137. //
  1138. Status = DbgReadMemory(Context,
  1139. TRUE,
  1140. BasePointer - PointerSize,
  1141. PointerSize * 2,
  1142. WorkingBuffer,
  1143. &BytesRead);
  1144. if ((Status != 0) || (BytesRead != (PointerSize * 2))) {
  1145. if (Status == 0) {
  1146. Status = EINVAL;
  1147. }
  1148. goto StackUnwindEnd;
  1149. }
  1150. //
  1151. // Store the return address for this function, then follow the base
  1152. // pointer to get the base pointer for the calling function.
  1153. //
  1154. RtlCopyMemory(&(Frame->ReturnAddress),
  1155. (PUCHAR)WorkingBuffer + PointerSize,
  1156. PointerSize);
  1157. Registers->Arm.R13Sp = BasePointer;
  1158. BasePointer = 0;
  1159. RtlCopyMemory(&BasePointer, WorkingBuffer, PointerSize);
  1160. Registers->Arm.R15Pc = Frame->ReturnAddress;
  1161. if ((Registers->Arm.R15Pc & ARM_THUMB_BIT) != 0) {
  1162. Registers->Arm.R7 = BasePointer;
  1163. Registers->Arm.Cpsr |= PSR_FLAG_THUMB;
  1164. } else {
  1165. Registers->Arm.R11Fp = BasePointer;
  1166. Registers->Arm.Cpsr &= ~PSR_FLAG_THUMB;
  1167. }
  1168. break;
  1169. default:
  1170. assert(FALSE);
  1171. Status = EINVAL;
  1172. }
  1173. StackUnwindEnd:
  1174. return Status;
  1175. }
  1176. INT
  1177. DbgPrintCallStack (
  1178. PDEBUGGER_CONTEXT Context,
  1179. PREGISTERS_UNION Registers,
  1180. BOOL PrintFrameNumbers
  1181. )
  1182. /*++
  1183. Routine Description:
  1184. This routine prints a call stack starting with the given registers.
  1185. Arguments:
  1186. Context - Supplies a pointer to the application context.
  1187. Registers - Supplies an optional pointer to the registers to use when
  1188. unwinding.
  1189. PrintFrameNumbers - Supplies a boolean indicating whether or not frame
  1190. numbers should be printed to the left of every frame.
  1191. Return Value:
  1192. 0 on success.
  1193. Returns an error code on failure.
  1194. --*/
  1195. {
  1196. ULONGLONG CallSite;
  1197. ULONG FrameCount;
  1198. ULONG FrameIndex;
  1199. PSTACK_FRAME Frames;
  1200. REGISTERS_UNION LocalRegisters;
  1201. INT Result;
  1202. Frames = NULL;
  1203. if (Registers == NULL) {
  1204. assert(Context->CurrentEvent.Type == DebuggerEventBreak);
  1205. memcpy(&LocalRegisters,
  1206. &(Context->CurrentEvent.BreakNotification.Registers),
  1207. sizeof(REGISTERS_UNION));
  1208. Registers = &LocalRegisters;
  1209. }
  1210. //
  1211. // Initialize the call site with the current instruction pointer.
  1212. //
  1213. CallSite = DbgGetPc(Context, Registers);
  1214. //
  1215. // Allocate the call stack frames buffer.
  1216. //
  1217. Frames = malloc(sizeof(STACK_FRAME) * MAX_CALL_STACK);
  1218. if (Frames == NULL) {
  1219. DbgOut("Failed to allocate memory for call stack buffer.\n");
  1220. Result = ENOMEM;
  1221. goto PrintCallStackEnd;
  1222. }
  1223. FrameCount = MAX_CALL_STACK;
  1224. Result = DbgGetCallStack(Context, Registers, Frames, &FrameCount);
  1225. if (Result != 0) {
  1226. DbgOut("Error: Failed to get call stack: %s.\n", strerror(Result));
  1227. }
  1228. //
  1229. // Print the column headings.
  1230. //
  1231. if (PrintFrameNumbers != FALSE) {
  1232. DbgOut("No ");
  1233. }
  1234. DbgOut("Frame RetAddr Call Site\n");
  1235. for (FrameIndex = 0; FrameIndex < FrameCount; FrameIndex += 1) {
  1236. if (PrintFrameNumbers != FALSE) {
  1237. DbgOut("%2d ", FrameIndex);
  1238. }
  1239. DbgOut("%08I64x %08I64x ",
  1240. Frames[FrameIndex].FramePointer,
  1241. Frames[FrameIndex].ReturnAddress);
  1242. //
  1243. // Attempt to print the call site location with symbols. If nothing was
  1244. // printed, fall back to printing the raw address.
  1245. //
  1246. DbgPrintAddressSymbol(Context, CallSite);
  1247. DbgOut("\n");
  1248. //
  1249. // The next stack frame's call site is this frame's return address. Set
  1250. // up the variables and loop again.
  1251. //
  1252. CallSite = Frames[FrameIndex].ReturnAddress;
  1253. }
  1254. Result = 0;
  1255. PrintCallStackEnd:
  1256. if (Frames != NULL) {
  1257. free(Frames);
  1258. }
  1259. return Result;
  1260. }
  1261. INT
  1262. DbgGetTargetInformation (
  1263. PDEBUGGER_CONTEXT Context,
  1264. PDEBUG_TARGET_INFORMATION TargetInformation,
  1265. ULONG TargetInformationSize
  1266. )
  1267. /*++
  1268. Routine Description:
  1269. This routine returns information about the machine being debugged.
  1270. Arguments:
  1271. Context - Supplies a pointer to the application context.
  1272. TargetInformation - Supplies a pointer where the target information will
  1273. be returned.
  1274. TargetInformationSize - Supplies the size of the target information buffer.
  1275. This must be the size of a debug target information structure.
  1276. Return Value:
  1277. 0 on success.
  1278. Returns an error code on failure.
  1279. --*/
  1280. {
  1281. if ((TargetInformation == NULL) ||
  1282. (TargetInformationSize != sizeof(DEBUG_TARGET_INFORMATION))) {
  1283. return ENOSPC;
  1284. }
  1285. RtlZeroMemory(TargetInformation, sizeof(DEBUG_TARGET_INFORMATION));
  1286. TargetInformation->MachineType = Context->MachineType;
  1287. return 0;
  1288. }
  1289. ULONG
  1290. DbgGetTargetPointerSize (
  1291. PDEBUGGER_CONTEXT Context
  1292. )
  1293. /*++
  1294. Routine Description:
  1295. This routine returns the size of a pointer on the target machine, in bytes.
  1296. Arguments:
  1297. Context - Supplies a pointer to the application context.
  1298. Return Value:
  1299. The size of a pointer on the target system, in bytes.
  1300. --*/
  1301. {
  1302. ULONG PointerSize;
  1303. switch (Context->MachineType) {
  1304. case MACHINE_TYPE_X86:
  1305. case MACHINE_TYPE_ARM:
  1306. PointerSize = sizeof(ULONG);
  1307. break;
  1308. default:
  1309. PointerSize = 0;
  1310. assert(FALSE);
  1311. break;
  1312. }
  1313. return PointerSize;
  1314. }
  1315. VOID
  1316. DbgGetStackRegisters (
  1317. PDEBUGGER_CONTEXT Context,
  1318. PREGISTERS_UNION Registers,
  1319. PULONGLONG StackPointer,
  1320. PULONGLONG FramePointer
  1321. )
  1322. /*++
  1323. Routine Description:
  1324. This routine returns the stack and/or frame pointer registers from a
  1325. given registers union.
  1326. Arguments:
  1327. Context - Supplies a pointer to the application context.
  1328. Registers - Supplies a pointer to the filled out registers union.
  1329. StackPointer - Supplies an optional pointer where the stack register value
  1330. will be returned.
  1331. FramePointer - Supplies an optional pointer where teh stack frame base
  1332. register value will be returned.
  1333. Return Value:
  1334. None.
  1335. --*/
  1336. {
  1337. ULONGLONG FrameValue;
  1338. ULONGLONG StackValue;
  1339. switch (Context->MachineType) {
  1340. case MACHINE_TYPE_X86:
  1341. StackValue = Registers->X86.Esp;
  1342. FrameValue = Registers->X86.Ebp;
  1343. break;
  1344. case MACHINE_TYPE_ARM:
  1345. StackValue = Registers->Arm.R13Sp;
  1346. if ((Registers->Arm.Cpsr & PSR_FLAG_THUMB) != 0) {
  1347. FrameValue = Registers->Arm.R7;
  1348. } else {
  1349. FrameValue = Registers->Arm.R11Fp;
  1350. }
  1351. break;
  1352. default:
  1353. assert(FALSE);
  1354. StackValue = 0;
  1355. FrameValue = 0;
  1356. break;
  1357. }
  1358. if (StackPointer != NULL) {
  1359. *StackPointer = StackValue;
  1360. }
  1361. if (FramePointer != NULL) {
  1362. *FramePointer = FrameValue;
  1363. }
  1364. return;
  1365. }
  1366. ULONGLONG
  1367. DbgGetPc (
  1368. PDEBUGGER_CONTEXT Context,
  1369. PREGISTERS_UNION Registers
  1370. )
  1371. /*++
  1372. Routine Description:
  1373. This routine returns the value of the program counter (instruction pointer)
  1374. register in the given registers union.
  1375. Arguments:
  1376. Context - Supplies a pointer to the application context.
  1377. Registers - Supplies an optional pointer to the filled out registers union.
  1378. If NULL, then the registers from the current frame will be used.
  1379. Return Value:
  1380. Returns the instruction pointer member from the given registers.
  1381. --*/
  1382. {
  1383. ULONGLONG Value;
  1384. if (Registers == NULL) {
  1385. Registers = &(Context->FrameRegisters);
  1386. }
  1387. switch (Context->MachineType) {
  1388. case MACHINE_TYPE_X86:
  1389. Value = Registers->X86.Eip;
  1390. break;
  1391. case MACHINE_TYPE_ARM:
  1392. Value = Registers->Arm.R15Pc;
  1393. break;
  1394. default:
  1395. assert(FALSE);
  1396. Value = 0;
  1397. break;
  1398. }
  1399. return Value;
  1400. }
  1401. VOID
  1402. DbgSetPc (
  1403. PDEBUGGER_CONTEXT Context,
  1404. PREGISTERS_UNION Registers,
  1405. ULONGLONG Value
  1406. )
  1407. /*++
  1408. Routine Description:
  1409. This routine sets the value of the program counter (instruction pointer)
  1410. register in the given registers union.
  1411. Arguments:
  1412. Context - Supplies a pointer to the application context.
  1413. Registers - Supplies an optional pointer to the filled out registers union.
  1414. If NULL, then the registers from the current frame will be used.
  1415. Value - Supplies the new value to set.
  1416. Return Value:
  1417. None.
  1418. --*/
  1419. {
  1420. if (Registers == NULL) {
  1421. Registers = &(Context->FrameRegisters);
  1422. }
  1423. switch (Context->MachineType) {
  1424. case MACHINE_TYPE_X86:
  1425. Registers->X86.Eip = Value;
  1426. break;
  1427. case MACHINE_TYPE_ARM:
  1428. Registers->Arm.R15Pc = Value;
  1429. break;
  1430. default:
  1431. assert(FALSE);
  1432. break;
  1433. }
  1434. return;
  1435. }
  1436. //
  1437. // --------------------------------------------------------- Internal Functions
  1438. //
  1439. BOOL
  1440. DbgpKdContinue (
  1441. VOID
  1442. )
  1443. /*++
  1444. Routine Description:
  1445. This routine sends the "go" command to the target, signaling to continue
  1446. execution.
  1447. Arguments:
  1448. None.
  1449. Return Value:
  1450. Returns TRUE if successful, or FALSE if there was an error.
  1451. --*/
  1452. {
  1453. BOOL Result;
  1454. DbgTxPacket.Header.Command = DbgCommandGo;
  1455. DbgTxPacket.Header.PayloadSize = 0;
  1456. Result = DbgpKdSendPacket(&DbgTxPacket);
  1457. if (Result == FALSE) {
  1458. DbgOut("Error sending go command.\n");
  1459. }
  1460. return Result;
  1461. }
  1462. BOOL
  1463. DbgpKdSetRegisters (
  1464. PREGISTERS_UNION Registers
  1465. )
  1466. /*++
  1467. Routine Description:
  1468. This routine sets the registers of the kernel debugging target.
  1469. Arguments:
  1470. Registers - Supplies a pointer to the registers to set. All register values
  1471. will be written.
  1472. Return Value:
  1473. Returns TRUE if successful, or FALSE if there was an error.
  1474. --*/
  1475. {
  1476. BOOL Result;
  1477. DbgTxPacket.Header.Command = DbgCommandSetRegisters;
  1478. DbgTxPacket.Header.PayloadSize = sizeof(REGISTERS_UNION);
  1479. RtlCopyMemory(DbgTxPacket.Payload, Registers, sizeof(REGISTERS_UNION));
  1480. Result = DbgpKdSendPacket(&DbgTxPacket);
  1481. if (Result == FALSE) {
  1482. DbgOut("Error setting registers.\n");
  1483. }
  1484. return Result;
  1485. }
  1486. BOOL
  1487. DbgpKdGetSpecialRegisters (
  1488. PSPECIAL_REGISTERS_UNION SpecialRegisters
  1489. )
  1490. /*++
  1491. Routine Description:
  1492. This routine gets the special registers from the target.
  1493. Arguments:
  1494. SpecialRegisters - Supplies a pointer where the registers will be returned
  1495. on success.
  1496. Return Value:
  1497. Returns TRUE if successful, or FALSE if there was an error.
  1498. --*/
  1499. {
  1500. BOOL Result;
  1501. DbgTxPacket.Header.Command = DbgCommandGetSpecialRegisters;
  1502. DbgTxPacket.Header.PayloadSize = 0;
  1503. Result = DbgpKdSendPacket(&DbgTxPacket);
  1504. if (Result == FALSE) {
  1505. DbgOut("Error setting registers.\n");
  1506. }
  1507. Result = DbgpKdReceivePacket(&DbgRxPacket, 0, NULL);
  1508. if (Result == FALSE) {
  1509. goto KdGetSpecialRegistersEnd;
  1510. }
  1511. if (DbgRxPacket.Header.Command != DbgCommandReturnSpecialRegisters) {
  1512. DbgOut("Error: Got packet %d, expected special registers return.\n",
  1513. DbgRxPacket.Header.Command);
  1514. Result = FALSE;
  1515. goto KdGetSpecialRegistersEnd;
  1516. }
  1517. if (DbgRxPacket.Header.PayloadSize != sizeof(SPECIAL_REGISTERS_UNION)) {
  1518. DbgOut("Error: Unexpected payload size %d. Expected %d.\n",
  1519. DbgRxPacket.Header.PayloadSize,
  1520. sizeof(SPECIAL_REGISTERS_UNION));
  1521. Result = FALSE;
  1522. goto KdGetSpecialRegistersEnd;
  1523. }
  1524. RtlCopyMemory(SpecialRegisters,
  1525. DbgRxPacket.Payload,
  1526. sizeof(SPECIAL_REGISTERS_UNION));
  1527. Result = TRUE;
  1528. KdGetSpecialRegistersEnd:
  1529. return Result;
  1530. }
  1531. BOOL
  1532. DbgpKdSetSpecialRegisters (
  1533. PSET_SPECIAL_REGISTERS Command
  1534. )
  1535. /*++
  1536. Routine Description:
  1537. This routine sets the special registers from the target.
  1538. Arguments:
  1539. Command - Supplies a pointer to the details of the set special registers
  1540. command.
  1541. Return Value:
  1542. Returns TRUE if successful, or FALSE if there was an error.
  1543. --*/
  1544. {
  1545. BOOL Result;
  1546. DbgTxPacket.Header.Command = DbgCommandSetSpecialRegisters;
  1547. DbgTxPacket.Header.PayloadSize = sizeof(SET_SPECIAL_REGISTERS);
  1548. RtlCopyMemory(DbgTxPacket.Payload, Command, sizeof(SET_SPECIAL_REGISTERS));
  1549. Result = DbgpKdSendPacket(&DbgTxPacket);
  1550. if (Result == FALSE) {
  1551. DbgOut("Error: Failed to send set special registers.\n");
  1552. }
  1553. return Result;
  1554. }
  1555. BOOL
  1556. DbgpKdSingleStep (
  1557. VOID
  1558. )
  1559. /*++
  1560. Routine Description:
  1561. This routine steps one instruction in the kernel debugging target.
  1562. Arguments:
  1563. None.
  1564. Return Value:
  1565. Returns TRUE if successful, or FALSE if there was an error.
  1566. --*/
  1567. {
  1568. BOOL Result;
  1569. DbgTxPacket.Header.Command = DbgCommandSingleStep;
  1570. DbgTxPacket.Header.PayloadSize = 0;
  1571. Result = DbgpKdSendPacket(&DbgTxPacket);
  1572. if (Result == FALSE) {
  1573. DbgOut("Error sending single step command.\n");
  1574. }
  1575. return Result;
  1576. }
  1577. BOOL
  1578. DbgpKdWaitForEvent (
  1579. PDEBUGGER_EVENT Event
  1580. )
  1581. /*++
  1582. Routine Description:
  1583. This routine gets an event from the target, such as a break event or other
  1584. exception.
  1585. Arguments:
  1586. Event - Supplies a pointer where the event details will be returned.
  1587. Return Value:
  1588. Returns TRUE if successful, or FALSE if there was an error.
  1589. --*/
  1590. {
  1591. BOOL Result;
  1592. ULONG Retries;
  1593. BOOL Return;
  1594. BOOL TimeoutOccurred;
  1595. Retries = 5;
  1596. Return = FALSE;
  1597. while (Return == FALSE) {
  1598. //
  1599. // Attempt to get a packet from the target.
  1600. //
  1601. while (TRUE) {
  1602. //
  1603. // If the connection was reset, attempt to reinitialize.
  1604. //
  1605. if (DbgKdConnectionReset != FALSE) {
  1606. Event->Type = DebuggerEventShutdown;
  1607. Event->ShutdownNotification.ShutdownType =
  1608. ShutdownTypeSynchronizationLost;
  1609. Result = TRUE;
  1610. goto KdWaitForEventEnd;
  1611. }
  1612. Result = DbgpKdReceivePacket(&DbgRxPacket,
  1613. DEBUG_USER_POLL_MILLISECONDS,
  1614. &TimeoutOccurred);
  1615. //
  1616. // If the packet failed to be received from something other than
  1617. // a timeout, bail out.
  1618. //
  1619. if ((Result == FALSE) && (TimeoutOccurred == FALSE)) {
  1620. if (DbgKdConnectionReset != FALSE) {
  1621. continue;
  1622. }
  1623. DbgOut("Communication Error.\n");
  1624. goto KdWaitForEventEnd;
  1625. }
  1626. //
  1627. // If the packet was successfully received, break out of this loop.
  1628. //
  1629. if (Result != FALSE) {
  1630. break;
  1631. }
  1632. //
  1633. // A packet could not be received due to a timeout. Check to see if
  1634. // a break-in packet should be sent, and continue.
  1635. //
  1636. if ((DbgBreakInDesired != FALSE) &&
  1637. (DbgBreakInRequestSent == FALSE)) {
  1638. DbgTxPacket.Header.Command = DbgBreakRequest;
  1639. DbgTxPacket.Header.PayloadSize = 0;
  1640. Result = DbgpKdSendPacket(&DbgTxPacket);
  1641. if (Result == FALSE) {
  1642. if (DbgKdConnectionReset != FALSE) {
  1643. continue;
  1644. }
  1645. DbgOut("Error: Could not send break request.\n");
  1646. Retries -= 1;
  1647. if (Retries == 0) {
  1648. return FALSE;
  1649. }
  1650. }
  1651. DbgBreakInRequestSent = TRUE;
  1652. }
  1653. }
  1654. Return = TRUE;
  1655. switch (DbgRxPacket.Header.Command) {
  1656. //
  1657. // A breakpoint has been reached.
  1658. //
  1659. case DbgBreakNotification:
  1660. Event->Type = DebuggerEventBreak;
  1661. RtlCopyMemory(&(Event->BreakNotification),
  1662. DbgRxPacket.Payload,
  1663. sizeof(BREAK_NOTIFICATION));
  1664. DbgBreakInDesired = FALSE;
  1665. DbgBreakInRequestSent = FALSE;
  1666. break;
  1667. //
  1668. // A shutdown occurred.
  1669. //
  1670. case DbgShutdownNotification:
  1671. Event->Type = DebuggerEventShutdown;
  1672. RtlCopyMemory(&(Event->ShutdownNotification),
  1673. DbgRxPacket.Payload,
  1674. sizeof(SHUTDOWN_NOTIFICATION));
  1675. break;
  1676. //
  1677. // The profiler sent some data. Because the profiler notification has
  1678. // a variable data array, the event only stores a pointer to a global
  1679. // buffer for the current profiler notification.
  1680. //
  1681. case DbgProfilerNotification:
  1682. Event->Type = DebuggerEventProfiler;
  1683. assert(DbgRxPacket.Header.PayloadSize <= DEBUG_PAYLOAD_SIZE);
  1684. Event->ProfilerNotification =
  1685. (PPROFILER_NOTIFICATION)(DbgRxPacket.Payload);
  1686. break;
  1687. default:
  1688. //
  1689. // The target sent an unknown command.
  1690. //
  1691. DbgOut("Unknown event received: 0x%x\n",
  1692. DbgRxPacket.Header.Command);
  1693. Return = FALSE;
  1694. }
  1695. if (Return != FALSE) {
  1696. break;
  1697. }
  1698. }
  1699. Result = TRUE;
  1700. KdWaitForEventEnd:
  1701. return Result;
  1702. }
  1703. BOOL
  1704. DbgpKdRangeStep (
  1705. PRANGE_STEP RangeStep
  1706. )
  1707. /*++
  1708. Routine Description:
  1709. This routine continues execution until a range of execution addresses is
  1710. reached.
  1711. Arguments:
  1712. RangeStep - Supplies a pointer to the range to go to.
  1713. Return Value:
  1714. Returns TRUE if successful, or FALSE on failure.
  1715. --*/
  1716. {
  1717. BOOL Result;
  1718. DbgTxPacket.Header.Command = DbgCommandRangeStep;
  1719. DbgTxPacket.Header.PayloadSize = sizeof(RANGE_STEP);
  1720. RtlCopyMemory(DbgTxPacket.Payload, RangeStep, sizeof(RANGE_STEP));
  1721. Result = DbgpKdSendPacket(&DbgTxPacket);
  1722. if (Result == FALSE) {
  1723. DbgOut("Error sending single step command.\n");
  1724. }
  1725. return Result;
  1726. }
  1727. BOOL
  1728. DbgpKdSwitchProcessors (
  1729. ULONG ProcessorNumber
  1730. )
  1731. /*++
  1732. Routine Description:
  1733. This routine switches the debugger to another processor.
  1734. Arguments:
  1735. ProcessorNumber - Supplies the processor number to switch to.
  1736. Return Value:
  1737. Returns TRUE if successful, or FALSE if there was no change.
  1738. --*/
  1739. {
  1740. PSWITCH_PROCESSOR_REQUEST Request;
  1741. BOOL Result;
  1742. //
  1743. // Send the switch command.
  1744. //
  1745. DbgTxPacket.Header.Command = DbgCommandSwitchProcessor;
  1746. Request = (PSWITCH_PROCESSOR_REQUEST)(DbgTxPacket.Payload);
  1747. DbgTxPacket.Header.PayloadSize = sizeof(SWITCH_PROCESSOR_REQUEST);
  1748. RtlZeroMemory(Request, sizeof(SWITCH_PROCESSOR_REQUEST));
  1749. Request->ProcessorNumber = ProcessorNumber;
  1750. Result = DbgpKdSendPacket(&DbgTxPacket);
  1751. return Result;
  1752. }
  1753. BOOL
  1754. DbgpKdGetLoadedModuleList (
  1755. PMODULE_LIST_HEADER *ModuleList
  1756. )
  1757. /*++
  1758. Routine Description:
  1759. This routine retrieves the list of loaded binaries from the kernel
  1760. debugging target.
  1761. Arguments:
  1762. ModuleList - Supplies a pointer where a pointer to the loaded module header
  1763. and subsequent array of entries will be returned. It is the caller's
  1764. responsibility to free this allocated memory when finished.
  1765. Return Value:
  1766. Returns TRUE on success, or FALSE on failure.
  1767. --*/
  1768. {
  1769. ULONG AllocationSize;
  1770. PMODULE_LIST_HEADER List;
  1771. ULONG ModuleCount;
  1772. PMODULE_LIST_HEADER ModuleListHeader;
  1773. ULONG Offset;
  1774. PLOADED_MODULE_ENTRY PacketModuleEntry;
  1775. BOOL Result;
  1776. List = NULL;
  1777. //
  1778. // Request the loaded modules list header to determine how many modules
  1779. // are loaded in the target.
  1780. //
  1781. DbgTxPacket.Header.Command = DbgModuleListEntriesRequest;
  1782. DbgTxPacket.Header.PayloadSize = 0;
  1783. Result = DbgpKdSendPacket(&DbgTxPacket);
  1784. if (Result == FALSE) {
  1785. DbgOut("Failed to send list entries request.\n");
  1786. goto KdGetLoadedModuleListEnd;
  1787. }
  1788. Result = DbgpKdReceivePacket(&DbgRxPacket, 0, NULL);
  1789. if ((Result == FALSE) ||
  1790. (DbgRxPacket.Header.Command != DbgModuleListHeader)) {
  1791. DbgOut("Failed to receive list header. Got %d %d\n",
  1792. Result,
  1793. DbgRxPacket.Header.Command);
  1794. Result = FALSE;
  1795. goto KdGetLoadedModuleListEnd;
  1796. }
  1797. ModuleListHeader = (PMODULE_LIST_HEADER)DbgRxPacket.Payload;
  1798. //
  1799. // Allocate space for the header and no entries.
  1800. //
  1801. ModuleCount = ModuleListHeader->ModuleCount;
  1802. AllocationSize = sizeof(MODULE_LIST_HEADER);
  1803. List = malloc(AllocationSize);
  1804. if (List == NULL) {
  1805. DbgOut("Error: Failed to allocate %d bytes for module list.\n",
  1806. AllocationSize);
  1807. Result = FALSE;
  1808. goto KdGetLoadedModuleListEnd;
  1809. }
  1810. RtlZeroMemory(List, AllocationSize);
  1811. RtlCopyMemory(List, ModuleListHeader, sizeof(MODULE_LIST_HEADER));
  1812. Offset = sizeof(MODULE_LIST_HEADER);
  1813. PacketModuleEntry = (PLOADED_MODULE_ENTRY)(DbgRxPacket.Payload);
  1814. //
  1815. // Get all modules. For each module, attempt to match it to an existing
  1816. // loaded module. If none is found, attempt to load the module.
  1817. //
  1818. while (ModuleCount != 0) {
  1819. Result = DbgpKdReceivePacket(&DbgRxPacket, 0, NULL);
  1820. if ((Result == FALSE) ||
  1821. (DbgRxPacket.Header.Command != DbgModuleListEntry) ||
  1822. (PacketModuleEntry->StructureSize < sizeof(LOADED_MODULE_ENTRY))) {
  1823. DbgOut("Failed to get module list. Got %x %x %x\n",
  1824. Result,
  1825. DbgRxPacket.Header.Command,
  1826. PacketModuleEntry->StructureSize);
  1827. Result = FALSE;
  1828. goto KdGetLoadedModuleListEnd;
  1829. }
  1830. AllocationSize += PacketModuleEntry->StructureSize;
  1831. List = realloc(List, AllocationSize);
  1832. if (List == NULL) {
  1833. DbgOut("Error: Failed to realloc %d bytes (for entry of %d "
  1834. "bytes).\n",
  1835. AllocationSize,
  1836. PacketModuleEntry->StructureSize);
  1837. Result = FALSE;
  1838. goto KdGetLoadedModuleListEnd;
  1839. }
  1840. RtlCopyMemory((PUCHAR)List + Offset,
  1841. DbgRxPacket.Payload,
  1842. PacketModuleEntry->StructureSize);
  1843. Offset += PacketModuleEntry->StructureSize;
  1844. ModuleCount -= 1;
  1845. }
  1846. KdGetLoadedModuleListEnd:
  1847. if (Result == FALSE) {
  1848. if (List != NULL) {
  1849. free(List);
  1850. List = NULL;
  1851. }
  1852. }
  1853. *ModuleList = List;
  1854. return Result;
  1855. }
  1856. BOOL
  1857. DbgpKdReadWriteMemory (
  1858. BOOL WriteOperation,
  1859. BOOL VirtualMemory,
  1860. ULONGLONG Address,
  1861. PVOID Buffer,
  1862. ULONG BufferSize,
  1863. PULONG BytesCompleted
  1864. )
  1865. /*++
  1866. Routine Description:
  1867. This routine retrieves or writes to the kernel target's memory.
  1868. Arguments:
  1869. WriteOperation - Supplies a flag indicating whether this is a read
  1870. operation (FALSE) or a write operation (TRUE).
  1871. VirtualMemory - Supplies a flag indicating whether the memory accessed
  1872. should be virtual or physical.
  1873. Address - Supplies the address to read from or write to in the target's
  1874. memory.
  1875. Buffer - Supplies a pointer to the buffer where the memory contents will be
  1876. returned for read operations, or supplies a pointer to the values to
  1877. write to memory on for write operations.
  1878. BufferSize - Supplies the size of the supplied buffer, in bytes.
  1879. BytesCompleted - Supplies a pointer that receive the number of bytes that
  1880. were actually read from or written to the target.
  1881. Return Value:
  1882. Returns TRUE if the operation was successful.
  1883. FALSE if there was an error.
  1884. --*/
  1885. {
  1886. PSTR AccessString;
  1887. ULONG BytesThisRound;
  1888. ULONG MaxSize;
  1889. PBYTE PacketData;
  1890. PMEMORY_REQUEST Request;
  1891. PMEMORY_CONTENTS Response;
  1892. BOOL Result;
  1893. PWRITE_REQUEST_ACKNOWLEDGEMENT WriteAcknowledge;
  1894. *BytesCompleted = 0;
  1895. Result = TRUE;
  1896. if (DbgKdPrintMemoryAccesses != FALSE) {
  1897. AccessString = "Read";
  1898. if (WriteOperation != FALSE) {
  1899. AccessString = "Write";
  1900. }
  1901. printf("%s %d bytes at address %08I64x.\n",
  1902. AccessString,
  1903. BufferSize,
  1904. Address);
  1905. }
  1906. //
  1907. // Currently only virtual reads are supported.
  1908. //
  1909. if (VirtualMemory == FALSE) {
  1910. Result = FALSE;
  1911. goto KdReadWriteMemoryEnd;
  1912. }
  1913. //
  1914. // Calculate the maximum amount of data that can be transferred in one
  1915. // packet. If the request is larger than that, it will need to be broken up.
  1916. //
  1917. if (WriteOperation != FALSE) {
  1918. MaxSize = DEBUG_PACKET_SIZE - sizeof(DEBUG_PACKET_HEADER) -
  1919. sizeof(MEMORY_REQUEST);
  1920. } else {
  1921. MaxSize = DEBUG_PACKET_SIZE - sizeof(DEBUG_PACKET_HEADER) -
  1922. sizeof(MEMORY_CONTENTS);
  1923. }
  1924. Request = (PMEMORY_REQUEST)DbgTxPacket.Payload;
  1925. while (*BytesCompleted < BufferSize) {
  1926. //
  1927. // If the request is too big for one packet, cap it.
  1928. //
  1929. if (BufferSize - *BytesCompleted > MaxSize) {
  1930. BytesThisRound = MaxSize;
  1931. } else {
  1932. BytesThisRound = BufferSize - *BytesCompleted;
  1933. }
  1934. DbgTxPacket.Header.PayloadSize = sizeof(MEMORY_REQUEST);
  1935. if (WriteOperation != FALSE) {
  1936. DbgTxPacket.Header.Command = DbgMemoryWriteVirtual;
  1937. DbgTxPacket.Header.PayloadSize += BytesThisRound;
  1938. memcpy(Request + 1, Buffer + *BytesCompleted, BytesThisRound);
  1939. } else {
  1940. DbgTxPacket.Header.Command = DbgMemoryReadVirtual;
  1941. }
  1942. Request->Address = Address;
  1943. Request->Size = BytesThisRound;
  1944. //
  1945. // Send the request packet and get the response.
  1946. //
  1947. Result = DbgpKdSendPacket(&DbgTxPacket);
  1948. if (Result == FALSE) {
  1949. goto KdReadWriteMemoryEnd;
  1950. }
  1951. Result = DbgpKdReceivePacket(&DbgRxPacket, 0, NULL);
  1952. if (Result == FALSE) {
  1953. goto KdReadWriteMemoryEnd;
  1954. }
  1955. //
  1956. // Verify the packet that was received, and bail out if it was
  1957. // unexpected.
  1958. //
  1959. if (DbgRxPacket.Header.Command == DbgInvalidCommand) {
  1960. DbgOut("Error: Target rejected the memory request!\n");
  1961. Result = FALSE;
  1962. goto KdReadWriteMemoryEnd;
  1963. }
  1964. //
  1965. // Handle the result from a write operation.
  1966. //
  1967. if (WriteOperation != FALSE) {
  1968. if ((DbgRxPacket.Header.Command != DbgMemoryWriteAcknowledgement) ||
  1969. (DbgRxPacket.Header.PayloadSize !=
  1970. sizeof(WRITE_REQUEST_ACKNOWLEDGEMENT))) {
  1971. DbgOut("Error: Received garbage command %d from target!\n",
  1972. DbgRxPacket.Header.Command);
  1973. Result = FALSE;
  1974. goto KdReadWriteMemoryEnd;
  1975. }
  1976. WriteAcknowledge =
  1977. (PWRITE_REQUEST_ACKNOWLEDGEMENT)DbgRxPacket.Payload;
  1978. *BytesCompleted += WriteAcknowledge->BytesWritten;
  1979. BufferSize -= WriteAcknowledge->BytesWritten;
  1980. Address += WriteAcknowledge->BytesWritten;
  1981. //
  1982. // If the target didn't write as much as requested, stop asking.
  1983. //
  1984. if (WriteAcknowledge->BytesWritten != BytesThisRound) {
  1985. break;
  1986. }
  1987. //
  1988. // Handle the result from a read operation.
  1989. //
  1990. } else {
  1991. if ((DbgRxPacket.Header.Command != DbgMemoryContents) ||
  1992. (DbgRxPacket.Header.PayloadSize < sizeof(MEMORY_CONTENTS))) {
  1993. DbgOut("Error: Received garbage command %d from target!\n",
  1994. DbgRxPacket.Header.Command);
  1995. Result = FALSE;
  1996. goto KdReadWriteMemoryEnd;
  1997. }
  1998. //
  1999. // Get the data from the packet and put it in the buffer.
  2000. //
  2001. Response = (PMEMORY_CONTENTS)DbgRxPacket.Payload;
  2002. PacketData = (PBYTE)DbgRxPacket.Payload + sizeof(MEMORY_CONTENTS);
  2003. RtlCopyMemory(Buffer + *BytesCompleted, PacketData, Response->Size);
  2004. *BytesCompleted += Response->Size;
  2005. Address += Response->Size;
  2006. //
  2007. // If the target didn't return as much data as requested, then don't
  2008. // request any more.
  2009. //
  2010. if (Response->Size != BytesThisRound) {
  2011. break;
  2012. }
  2013. }
  2014. }
  2015. KdReadWriteMemoryEnd:
  2016. return Result;
  2017. }
  2018. BOOL
  2019. DbgpKdReboot (
  2020. DEBUG_REBOOT_TYPE RebootType
  2021. )
  2022. /*++
  2023. Routine Description:
  2024. This routine forcefully reboots the target machine.
  2025. Arguments:
  2026. RebootType - Supplies the reboot type.
  2027. Return Value:
  2028. Returns TRUE if successful, or FALSE if there was no change.
  2029. --*/
  2030. {
  2031. PDEBUG_REBOOT_REQUEST Request;
  2032. BOOL Result;
  2033. //
  2034. // Send the reboot command.
  2035. //
  2036. DbgTxPacket.Header.Command = DbgCommandReboot;
  2037. Request = (PDEBUG_REBOOT_REQUEST)(DbgTxPacket.Payload);
  2038. DbgTxPacket.Header.PayloadSize = sizeof(DEBUG_REBOOT_REQUEST);
  2039. RtlZeroMemory(Request, sizeof(DEBUG_REBOOT_REQUEST));
  2040. Request->ResetType = RebootType;
  2041. Result = DbgpKdSendPacket(&DbgTxPacket);
  2042. return Result;
  2043. }
  2044. BOOL
  2045. DbgpKdSendPacket (
  2046. PDEBUG_PACKET Packet
  2047. )
  2048. /*++
  2049. Routine Description:
  2050. This routine sends a packet across the wire to the debugging target when
  2051. connected to a kernel.
  2052. Arguments:
  2053. Packet - Supplies a pointer to the debug packet. The checksum field will be
  2054. calculated in this function.
  2055. Return Value:
  2056. TRUE if successful, FALSE on error.
  2057. --*/
  2058. {
  2059. DEBUG_PACKET_HEADER Acknowledge;
  2060. USHORT Checksum;
  2061. ULONG HeaderSize;
  2062. ULONG Retries;
  2063. BOOL Status;
  2064. BOOL TimeoutOccurred;
  2065. HeaderSize = sizeof(DEBUG_PACKET_HEADER);
  2066. Status = FALSE;
  2067. if (Packet->Header.PayloadSize > DEBUG_PACKET_SIZE - HeaderSize) {
  2068. DbgOut("Error: Oversized packet attempting to be sent!\n");
  2069. return FALSE;
  2070. }
  2071. Packet->Header.Magic = DEBUG_PACKET_MAGIC;
  2072. Packet->Header.PayloadSizeComplement = ~(Packet->Header.PayloadSize);
  2073. Packet->Header.Checksum = 0;
  2074. Checksum = DbgpKdCalculateChecksum(Packet,
  2075. Packet->Header.PayloadSize + HeaderSize);
  2076. Packet->Header.Checksum = Checksum;
  2077. Retries = 10;
  2078. while (Retries > 0) {
  2079. //
  2080. // Send the packet, then attempt to receive the response acknowledge.
  2081. //
  2082. Status = DbgpKdSendBytes(Packet,
  2083. HeaderSize + Packet->Header.PayloadSize);
  2084. if (Status == FALSE) {
  2085. DbgOut("Error: Unable to send packet!\n");
  2086. break;
  2087. }
  2088. Status = DbgpKdReceivePacketHeader(&Acknowledge,
  2089. 5000,
  2090. &TimeoutOccurred);
  2091. if ((Status != FALSE) &&
  2092. (Acknowledge.Command == DbgPacketAcknowledge)) {
  2093. Status = TRUE;
  2094. break;
  2095. }
  2096. //
  2097. // If nonsense seems to have been received, start over.
  2098. //
  2099. Retries -= 1;
  2100. Status = FALSE;
  2101. }
  2102. return Status;
  2103. }
  2104. BOOL
  2105. DbgpKdReceivePacket (
  2106. PDEBUG_PACKET Packet,
  2107. ULONG TimeoutMilliseconds,
  2108. PBOOL TimeoutOccurred
  2109. )
  2110. /*++
  2111. Routine Description:
  2112. This routine receives a packet across the wire from the host when connected
  2113. to a kernel.
  2114. Arguments:
  2115. Packet - Supplies a pointer to the buffer that will receive the debug
  2116. packet.
  2117. TimeoutMilliseconds - Supplies the number of milliseconds to wait for a
  2118. packet before giving up. Once a packet header has been received, the
  2119. function will block until an entire packet is received.
  2120. TimeoutOccurred - Supplies an optional pointer to a boolean indicating that
  2121. the timeout occurred before a header could be received.
  2122. Return Value:
  2123. TRUE if a packet was received.
  2124. FALSE if a communication error occurred.
  2125. --*/
  2126. {
  2127. DEBUG_COMPLETE_ACKNOWLEDGE_PACKET Acknowledge;
  2128. USHORT CalculatedChecksum;
  2129. USHORT Checksum;
  2130. USHORT HeaderChecksum;
  2131. ULONG HeaderSize;
  2132. PSTR LastCharacter;
  2133. ULONG Retries;
  2134. BOOL Status;
  2135. HeaderSize = sizeof(DEBUG_PACKET_HEADER);
  2136. Retries = 10;
  2137. if (TimeoutOccurred != NULL) {
  2138. *TimeoutOccurred = FALSE;
  2139. }
  2140. while (TRUE) {
  2141. Status = DbgpKdReceivePacketHeader(&(Packet->Header),
  2142. TimeoutMilliseconds,
  2143. TimeoutOccurred);
  2144. if (Status == FALSE) {
  2145. break;
  2146. }
  2147. //
  2148. // If the packet has a payload, get that as well.
  2149. //
  2150. if (Packet->Header.PayloadSize != 0) {
  2151. Status = DbgpKdReceiveBytes(&(Packet->Payload),
  2152. Packet->Header.PayloadSize);
  2153. if (Status == FALSE) {
  2154. DbgOut("Error: Unable to receive packet payload.\n");
  2155. goto KdReceivePacketHeaderRetry;
  2156. }
  2157. }
  2158. //
  2159. // Ensure that the packet came across okay. The checksum field is not
  2160. // included in the checksum calculation, so zero it out while
  2161. // calculating.
  2162. //
  2163. HeaderChecksum = Packet->Header.Checksum;
  2164. Packet->Header.Checksum = 0;
  2165. CalculatedChecksum = DbgpKdCalculateChecksum(
  2166. Packet,
  2167. HeaderSize + Packet->Header.PayloadSize);
  2168. Packet->Header.Checksum = HeaderChecksum;
  2169. if (HeaderChecksum != CalculatedChecksum) {
  2170. DbgOut("Error: Checksum mismatch on received packet!\n"
  2171. "Calculated %x Header %x\n",
  2172. CalculatedChecksum,
  2173. HeaderChecksum);
  2174. goto KdReceivePacketHeaderRetry;
  2175. }
  2176. //
  2177. // Ignore spurious acknowledges.
  2178. //
  2179. if (Packet->Header.Command == DbgPacketAcknowledge) {
  2180. DbgOut("Skipping spurious acknowledge.\n");
  2181. continue;
  2182. }
  2183. //
  2184. // The payload is okay. Send the acknowledge and break.
  2185. //
  2186. RtlZeroMemory(&Acknowledge, sizeof(DEBUG_COMPLETE_ACKNOWLEDGE_PACKET));
  2187. Acknowledge.Header.Magic = DEBUG_PACKET_MAGIC;
  2188. Acknowledge.Header.Command = DbgPacketAcknowledge;
  2189. Acknowledge.Header.PayloadSize = sizeof(DEBUG_PACKET_ACKNOWLEDGE);
  2190. Acknowledge.Header.PayloadSizeComplement =
  2191. ~(Acknowledge.Header.PayloadSize);
  2192. Acknowledge.Acknowledge.BreakInRequested = DbgBreakInDesired;
  2193. Checksum = DbgpKdCalculateChecksum(
  2194. &Acknowledge,
  2195. sizeof(DEBUG_COMPLETE_ACKNOWLEDGE_PACKET));
  2196. Acknowledge.Header.Checksum = Checksum;
  2197. Status = DbgpKdSendBytes(&Acknowledge,
  2198. sizeof(DEBUG_COMPLETE_ACKNOWLEDGE_PACKET));
  2199. if (Status == FALSE) {
  2200. goto KdReceivePacketHeaderRetry;
  2201. }
  2202. //
  2203. // Handle certain events inline.
  2204. //
  2205. if (Packet->Header.Command == DbgPrintString) {
  2206. LastCharacter = ((PCHAR)(Packet->Payload)) + DEBUG_PAYLOAD_SIZE - 1;
  2207. //
  2208. // Terminate the last character for safety, and print out the
  2209. // string.
  2210. //
  2211. *LastCharacter = '\0';
  2212. DbgOut("%s", Packet->Payload);
  2213. continue;
  2214. }
  2215. Status = TRUE;
  2216. break;
  2217. KdReceivePacketHeaderRetry:
  2218. if (Retries == 0) {
  2219. Status = FALSE;
  2220. break;
  2221. }
  2222. //
  2223. // Ask the host to resend and loop.
  2224. //
  2225. DbgOut("Asking for Resend, %d retries.\n", Retries);
  2226. Acknowledge.Header.Command = DbgPacketResend;
  2227. Acknowledge.Header.PayloadSize = 0;
  2228. Acknowledge.Header.PayloadSizeComplement =
  2229. ~(Acknowledge.Header.PayloadSize);
  2230. Checksum = DbgpKdCalculateChecksum(&Acknowledge,
  2231. sizeof(DEBUG_PACKET_HEADER));
  2232. Acknowledge.Header.Checksum = Checksum;
  2233. Status = DbgpKdSendBytes(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  2234. if (Status == FALSE) {
  2235. break;
  2236. }
  2237. Retries -= 1;
  2238. }
  2239. return Status;
  2240. }
  2241. BOOL
  2242. DbgpKdReceivePacketHeader (
  2243. PDEBUG_PACKET_HEADER Packet,
  2244. ULONG TimeoutMilliseconds,
  2245. PBOOL TimeoutOccurred
  2246. )
  2247. /*++
  2248. Routine Description:
  2249. This routine receives a packet header across the wire from the host when
  2250. connected to a kernel.
  2251. Arguments:
  2252. Packet - Supplies a pointer to the buffer that will receive the debug
  2253. packet header.
  2254. TimeoutMilliseconds - Supplies the number of milliseconds to wait for a
  2255. packet before giving up. Once a packet header has been received, the
  2256. function will block until an entire packet is received.
  2257. TimeoutOccurred - Supplies an optional pointer to a boolean indicating that
  2258. the timeout occurred before a header could be received.
  2259. Return Value:
  2260. TRUE if a packet was received.
  2261. FALSE if a communication error occurred.
  2262. --*/
  2263. {
  2264. ULONG BytesAvailable;
  2265. ULONG HeaderSize;
  2266. UCHAR Magic;
  2267. ULONG Retries;
  2268. BOOL Status;
  2269. ULONG TimeWaited;
  2270. HeaderSize = sizeof(DEBUG_PACKET_HEADER);
  2271. if (TimeoutOccurred != NULL) {
  2272. *TimeoutOccurred = FALSE;
  2273. }
  2274. Retries = 10;
  2275. while (Retries != 0) {
  2276. //
  2277. // If a timeout is specified, ensure that at least a header's worth of
  2278. // data is available. If the timeout expires, return.
  2279. //
  2280. if (TimeoutMilliseconds != 0) {
  2281. TimeWaited = 0;
  2282. while (TRUE) {
  2283. BytesAvailable = CommReceiveBytesReady();
  2284. if (BytesAvailable != 0) {
  2285. break;
  2286. }
  2287. CommStall(15);
  2288. TimeWaited += 15;
  2289. if (TimeWaited >= TimeoutMilliseconds) {
  2290. if (TimeoutOccurred != NULL) {
  2291. *TimeoutOccurred = TRUE;
  2292. }
  2293. return FALSE;
  2294. }
  2295. }
  2296. }
  2297. //
  2298. // Attempt to synchronize on the magic field.
  2299. //
  2300. Magic = 0;
  2301. Status = DbgpKdReceiveBytes(&Magic, 1);
  2302. if (Status == FALSE) {
  2303. Retries -= 1;
  2304. continue;
  2305. }
  2306. if (Magic != DEBUG_PACKET_MAGIC_BYTE1) {
  2307. //
  2308. // Check for a resynchronization byte, indicating the target is
  2309. // new or confused. If the state is already reset, then this is
  2310. // probably during the initial connect, where extra resync bytes
  2311. // from the target are ignored.
  2312. //
  2313. if ((Magic == DEBUG_SYNCHRONIZE_TARGET) &&
  2314. (DbgKdConnectionReset == FALSE)) {
  2315. DbgKdConnectionReset = TRUE;
  2316. Status = FALSE;
  2317. break;
  2318. }
  2319. continue;
  2320. }
  2321. Magic = 0;
  2322. Status = DbgpKdReceiveBytes(&Magic, 1);
  2323. if (Status == FALSE) {
  2324. Retries -= 1;
  2325. continue;
  2326. }
  2327. if (Magic != DEBUG_PACKET_MAGIC_BYTE2) {
  2328. continue;
  2329. }
  2330. //
  2331. // Get the packet header. Sometimes this is all that's required.
  2332. //
  2333. Packet->Magic = DEBUG_PACKET_MAGIC;
  2334. Status = DbgpKdReceiveBytes((PUCHAR)Packet + DEBUG_PACKET_MAGIC_SIZE,
  2335. HeaderSize - DEBUG_PACKET_MAGIC_SIZE);
  2336. if (Status == FALSE) {
  2337. DbgOut("Error: Unable to receive packet header!\n");
  2338. Retries -= 1;
  2339. continue;
  2340. }
  2341. if ((USHORT)~(Packet->PayloadSize) != Packet->PayloadSizeComplement) {
  2342. DbgOut("Resynchronizing due to payload size complement "
  2343. "mismatch.\n");
  2344. Retries -= 1;
  2345. Status = FALSE;
  2346. continue;
  2347. }
  2348. if (Packet->PayloadSize > DEBUG_PACKET_SIZE - HeaderSize) {
  2349. DbgOut("Error: Oversized packet received. Command 0x%x, "
  2350. "PayloadSize 0x%x.\n",
  2351. Packet->Command,
  2352. Packet->PayloadSize);
  2353. Retries -= 1;
  2354. Status = FALSE;
  2355. continue;
  2356. }
  2357. Status = TRUE;
  2358. break;
  2359. }
  2360. return Status;
  2361. }
  2362. INT
  2363. DbgpKdSynchronize (
  2364. VOID
  2365. )
  2366. /*++
  2367. Routine Description:
  2368. This routine synchronizes with the target machine, making sure it is ready
  2369. to receive the connection request.
  2370. Arguments:
  2371. None.
  2372. Return Value:
  2373. 0 on success.
  2374. Non-zero on error.
  2375. --*/
  2376. {
  2377. BOOL Result;
  2378. ULONG Retries;
  2379. ULONG Status;
  2380. UCHAR SynchronizeByte;
  2381. ULONG TimeWaited;
  2382. //
  2383. // Check to see if the target has already sent a sync to the host.
  2384. //
  2385. while (CommReceiveBytesReady() != 0) {
  2386. Result = DbgpKdReceiveBytes(&SynchronizeByte, sizeof(UCHAR));
  2387. if (Result == FALSE) {
  2388. Status = EPIPE;
  2389. goto KdSynchronizeEnd;
  2390. }
  2391. if (SynchronizeByte == DEBUG_SYNCHRONIZE_TARGET) {
  2392. Status = 0;
  2393. goto KdSynchronizeEnd;
  2394. }
  2395. }
  2396. Retries = 10;
  2397. while (Retries > 0) {
  2398. //
  2399. // Send a little query.
  2400. //
  2401. SynchronizeByte = DEBUG_SYNCHRONIZE_HOST;
  2402. Result = DbgpKdSendBytes(&SynchronizeByte, 1);
  2403. if (Result == FALSE) {
  2404. Status = EPIPE;
  2405. continue;
  2406. }
  2407. //
  2408. // Wait for a response.
  2409. //
  2410. TimeWaited = 0;
  2411. while (TimeWaited < 5000) {
  2412. if (CommReceiveBytesReady() != 0) {
  2413. Result = DbgpKdReceiveBytes(&SynchronizeByte, 1);
  2414. if (Result == FALSE) {
  2415. Status = EPIPE;
  2416. break;
  2417. }
  2418. if (SynchronizeByte == DEBUG_SYNCHRONIZE_TARGET) {
  2419. Status = 0;
  2420. goto KdSynchronizeEnd;
  2421. }
  2422. } else {
  2423. CommStall(15);
  2424. TimeWaited += 15;
  2425. }
  2426. }
  2427. Retries -= 1;
  2428. }
  2429. Status = EPIPE;
  2430. KdSynchronizeEnd:
  2431. return Status;
  2432. }
  2433. USHORT
  2434. DbgpKdCalculateChecksum (
  2435. PVOID Data,
  2436. ULONG DataLength
  2437. )
  2438. /*++
  2439. Routine Description:
  2440. This routine computes a checksum over a given length for kernel debug
  2441. transport packets. It can handle both odd and even length data.
  2442. Arguments:
  2443. Data - Supplies a pointer to the data that is to be checksummed.
  2444. DataLength - Supplies the length of the data buffer, in bytes.
  2445. Return Value:
  2446. Returns the checksum.
  2447. --*/
  2448. {
  2449. USHORT Checksum;
  2450. PUSHORT CurrentData;
  2451. ULONG Index;
  2452. ULONG ShortLength;
  2453. Checksum = 0;
  2454. Index = 0;
  2455. //
  2456. // Checksums are calculated by adding up a series of two-byte values.
  2457. // Convert the pointer to a short pointer and divide bytes by 2 to get size
  2458. // in shorts.
  2459. //
  2460. ShortLength = DataLength / 2;
  2461. CurrentData = (PUSHORT)Data;
  2462. while (Index < ShortLength) {
  2463. Checksum += *CurrentData;
  2464. CurrentData += 1;
  2465. Index += 1;
  2466. }
  2467. //
  2468. // If the data was an odd length, then there's one byte left to be added.
  2469. // Add only that byte.
  2470. //
  2471. if ((ShortLength * 2) != DataLength) {
  2472. Checksum += *((PUCHAR)CurrentData);
  2473. }
  2474. return Checksum;
  2475. }
  2476. BOOL
  2477. DbgpKdReceiveBytes (
  2478. PVOID Buffer,
  2479. ULONG BytesToRead
  2480. )
  2481. /*++
  2482. Routine Description:
  2483. This routine receives a number of bytes from the debugger connection.
  2484. Arguments:
  2485. Buffer - Supplies a pointer to the buffer where the data should be returned.
  2486. BytesToRead - Supplies the number of bytes that should be received into the
  2487. buffer.
  2488. Return Value:
  2489. Returns TRUE on success, FALSE on failure.
  2490. --*/
  2491. {
  2492. ULONG ByteIndex;
  2493. PUCHAR Bytes;
  2494. CHAR Character;
  2495. ULONG Count;
  2496. ULONG Index;
  2497. BOOL NextEscaped;
  2498. BOOL Status;
  2499. NextEscaped = FALSE;
  2500. Status = TRUE;
  2501. Bytes = Buffer;
  2502. while (BytesToRead != 0) {
  2503. Status = CommReceive(Bytes, BytesToRead);
  2504. if (Status == FALSE) {
  2505. DbgOut("Failed to receive %d bytes.\n", BytesToRead);
  2506. return Status;
  2507. }
  2508. if (DbgKdPrintRawBytes != FALSE) {
  2509. DbgOut("RX: ");
  2510. for (ByteIndex = 0; ByteIndex < BytesToRead; ByteIndex += 1) {
  2511. DbgOut("%02X ", Bytes[ByteIndex]);
  2512. }
  2513. DbgOut("\nRX: ");
  2514. for (ByteIndex = 0; ByteIndex < BytesToRead; ByteIndex += 1) {
  2515. Character = Bytes[ByteIndex];
  2516. if (!isprint(Character)) {
  2517. Character = '.';
  2518. }
  2519. DbgOut("%02c ", Character);
  2520. }
  2521. DbgOut("\n");
  2522. }
  2523. //
  2524. // If escaping is on, then remove any escape bytes found, and fix up
  2525. // the escaped byte.
  2526. //
  2527. Count = 0;
  2528. if (DbgKdEncodeBytes != FALSE) {
  2529. //
  2530. // If the last byte received was an escape, then unescape this
  2531. // first byte.
  2532. //
  2533. if (NextEscaped != FALSE) {
  2534. NextEscaped = FALSE;
  2535. Bytes[0] -= DEBUG_ESCAPE;
  2536. Bytes += 1;
  2537. BytesToRead -= 1;
  2538. if (BytesToRead == 0) {
  2539. break;
  2540. }
  2541. }
  2542. for (Index = 0; Index < BytesToRead - 1; Index += 1) {
  2543. if (Bytes[Index] == DEBUG_ESCAPE) {
  2544. memmove(&(Bytes[Index]),
  2545. &(Bytes[Index + 1]),
  2546. BytesToRead - Index - 1);
  2547. Count += 1;
  2548. Bytes[Index] -= DEBUG_ESCAPE;
  2549. }
  2550. }
  2551. if (Bytes[Index] == DEBUG_ESCAPE) {
  2552. Count += 1;
  2553. NextEscaped = TRUE;
  2554. }
  2555. }
  2556. Bytes += BytesToRead - Count;
  2557. BytesToRead = Count;
  2558. }
  2559. return Status;
  2560. }
  2561. BOOL
  2562. DbgpKdSendBytes (
  2563. PVOID Buffer,
  2564. ULONG BytesToSend
  2565. )
  2566. /*++
  2567. Routine Description:
  2568. This routine sends a number of bytes through the debugger connection.
  2569. Arguments:
  2570. Buffer - Supplies a pointer to the buffer where the data to be sent resides.
  2571. BytesToSend - Supplies the number of bytes that should be sent.
  2572. Return Value:
  2573. Returns TRUE on success, FALSE on failure.
  2574. --*/
  2575. {
  2576. ULONG ByteIndex;
  2577. PUCHAR Bytes;
  2578. UCHAR EncodedByte[2];
  2579. ULONG SendSize;
  2580. BOOL Status;
  2581. Bytes = Buffer;
  2582. if (DbgKdPrintRawBytes != FALSE) {
  2583. DbgOut("TX: ");
  2584. for (ByteIndex = 0; ByteIndex < BytesToSend; ByteIndex += 1) {
  2585. DbgOut("%02X ", Bytes[ByteIndex]);
  2586. }
  2587. DbgOut("\n");
  2588. }
  2589. Status = TRUE;
  2590. while (BytesToSend != 0) {
  2591. SendSize = 0;
  2592. if (DbgKdEncodeBytes != FALSE) {
  2593. //
  2594. // Gather bytes until one is found that needs escaping.
  2595. //
  2596. while ((SendSize < BytesToSend) &&
  2597. (Bytes[SendSize] != DEBUG_XON) &&
  2598. (Bytes[SendSize] != DEBUG_XOFF) &&
  2599. (Bytes[SendSize] != DEBUG_ESCAPE)) {
  2600. SendSize += 1;
  2601. }
  2602. //
  2603. // If no escaping is needed, just send everything.
  2604. //
  2605. } else {
  2606. SendSize = BytesToSend;
  2607. }
  2608. if (SendSize != 0) {
  2609. Status = CommSend(Bytes, SendSize);
  2610. if (Status == FALSE) {
  2611. DbgOut("Failed to send %d bytes.\n", BytesToSend);
  2612. break;
  2613. }
  2614. }
  2615. Bytes += SendSize;
  2616. BytesToSend -= SendSize;
  2617. if (BytesToSend != 0) {
  2618. EncodedByte[0] = DEBUG_ESCAPE;
  2619. EncodedByte[1] = *Bytes + DEBUG_ESCAPE;
  2620. Status = CommSend(EncodedByte, 2);
  2621. if (Status == FALSE) {
  2622. DbgOut("Failed to send %d bytes.\n", BytesToSend);
  2623. break;
  2624. }
  2625. Bytes += 1;
  2626. BytesToSend -= 1;
  2627. }
  2628. }
  2629. return Status;
  2630. }