kdebug.c 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. kdebug.c
  5. Abstract:
  6. This module implements the kernel debugging functionality.
  7. Author:
  8. Evan Green 3-Jul-2012
  9. Environment:
  10. Kernel mode
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/kernel.h>
  16. #include <minoca/kernel/bootload.h>
  17. #include <minoca/debug/dbgproto.h>
  18. #include "kdp.h"
  19. //
  20. // ---------------------------------------------------------------- Definitions
  21. //
  22. //
  23. // Define the increment to stall for in microseconds when waiting for a packet.
  24. //
  25. #define DEBUG_STALL_INCREMENT 1000
  26. //
  27. // Define the amount of time to wait if just waiting a little bit, not the full
  28. // stall increment yet.
  29. //
  30. #define DEBUG_SMALL_STALL 100
  31. //
  32. // Define the maximum size of the kernel module name.
  33. //
  34. #define MAX_KERNEL_MODULE_NAME 16
  35. //
  36. // Define the number of microseconds to wait for all other processors before
  37. // declaring them lost and entering the debugger anyway.
  38. //
  39. #define DEBUG_PROCESSOR_WAIT_TIME (10 * MICROSECONDS_PER_SECOND)
  40. //
  41. // ------------------------------------------------------ Data Type Definitions
  42. //
  43. /*++
  44. Structure Description:
  45. This structure defines a "range" breakpoint. This type of breakpoint will
  46. break on a range of addresses, with an optional "hole" within the range that
  47. will not cause a break. This type of breakpoint is very slow, as it puts
  48. the processor into single step mode and manually checks the range on every
  49. trap.
  50. Members:
  51. Enabled - Stores a flag indicating whether or not the range breakpoint is
  52. current enabled. If disabled (FALSE), none of the other fields are
  53. guaranteed to be initialized.
  54. BreakRangeStart - Stores a pointer to the first byte of memory that
  55. qualifies as being in the break range.
  56. BreakRangeEnd - Stores a pointer to the first byte of memory that does not
  57. qualify as being in the break range.
  58. RangeHoleStart - Stores a pointer to the first byte within the range that
  59. does not generate a break (a "hole" in the break range).
  60. RangeHoleEnd - Stores a pointer to the first byte within the range that does
  61. not fall in the range hole (the first byte that again qualifies as
  62. within the break range).
  63. --*/
  64. typedef struct _BREAK_RANGE {
  65. BOOL Enabled;
  66. PVOID BreakRangeStart;
  67. PVOID BreakRangeEnd;
  68. PVOID RangeHoleStart;
  69. PVOID RangeHoleEnd;
  70. } BREAK_RANGE, *PBREAK_RANGE;
  71. /*++
  72. Structure Description:
  73. This structure stores the set of parameters needed for a kernel debug print
  74. operation.
  75. Members:
  76. FormatString - Stores a pointer to the printf format string to print.
  77. Arguments - Stores the list of arguments needed by the format string.
  78. --*/
  79. typedef struct _PRINT_PARAMETERS {
  80. PSTR FormatString;
  81. va_list Arguments;
  82. } PRINT_PARAMETERS, *PPRINT_PARAMETERS;
  83. //
  84. // -------------------------------------------------------------------- Globals
  85. //
  86. //
  87. // Define globals indicating the initialization and connection state of Kd.
  88. //
  89. BOOL KdDebuggerConnected;
  90. BOOL KdDebuggingEnabled = TRUE;
  91. BOOL KdInitialized = FALSE;
  92. volatile ULONG KdLockAcquired = -1;
  93. volatile ULONG KdProcessorsFrozen = 0;
  94. volatile ULONG KdFreezeOwner = MAX_ULONG;
  95. BOOL KdNmiBroadcastAllowed = FALSE;
  96. //
  97. // Store a pointer to the debugger transport.
  98. //
  99. PDEBUG_DEVICE_DESCRIPTION KdDebugDevice;
  100. DEBUG_HANDOFF_DATA KdHandoffData;
  101. //
  102. // Set this flag to allow notable user mode exceptions to bubble up into the
  103. // kernel mode debugger.
  104. //
  105. BOOL KdEnableUserModeExceptions = TRUE;
  106. //
  107. // Set this flag to debug the time counter itself or situations where the time
  108. // counter may not be accessible or reliable.
  109. //
  110. BOOL KdAvoidTimeCounter = FALSE;
  111. //
  112. // Set this flag to enable encoding of certain characters that might not fly
  113. // across the wire well directly (like XON/XOFF).
  114. //
  115. BOOL KdEncodeBytes = FALSE;
  116. //
  117. // Variable used for one-time assertions.
  118. //
  119. BOOL KdAsserted = FALSE;
  120. //
  121. // Carve off some memory for sending and receiving debug packets, and storing
  122. // the currently loaded modules.
  123. //
  124. DEBUG_PACKET KdTxPacket;
  125. DEBUG_PACKET KdRxPacket;
  126. DEBUG_MODULE_LIST KdLoadedModules;
  127. BOOL KdLoadedModulesInitialized;
  128. //
  129. // Carve off memory to store the kernel module, including its string.
  130. //
  131. UCHAR KdKernelModuleBuffer[sizeof(DEBUG_MODULE) + MAX_KERNEL_MODULE_NAME];
  132. //
  133. // Store information about whether or not the user asked for a single step.
  134. //
  135. BOOL KdUserRequestedSingleStep;
  136. BREAK_RANGE KdBreakRange;
  137. UINTN KdPeriodicBreakInCheck;
  138. //
  139. // Variable used to determine whether or not memory validation should be
  140. // skipped.
  141. //
  142. BOOL KdSkipMemoryValidation = FALSE;
  143. //
  144. // Define the amount of time to wait in microseconds to wait for a connection
  145. // before moving on. Set to -1 to avoid using the stall function and wait
  146. // indefinitely.
  147. //
  148. ULONG KdConnectionTimeout = DEBUG_CONNECTION_TIMEOUT;
  149. //
  150. // ----------------------------------------------- Internal Function Prototypes
  151. //
  152. KSTATUS
  153. KdpSendPacket (
  154. PDEBUG_PACKET Packet,
  155. PBOOL BreakInRequested
  156. );
  157. KSTATUS
  158. KdpReceivePacket (
  159. PDEBUG_PACKET Packet,
  160. ULONG Timeout
  161. );
  162. KSTATUS
  163. KdpReceivePacketHeader (
  164. PDEBUG_PACKET_HEADER Packet,
  165. PULONG Timeout
  166. );
  167. KSTATUS
  168. KdpProcessCommand (
  169. PDEBUG_PACKET Packet,
  170. ULONG Exception,
  171. PTRAP_FRAME TrapFrame,
  172. PBOOL ContinueExecution
  173. );
  174. KSTATUS
  175. KdpPrint (
  176. PPRINT_PARAMETERS PrintParameters,
  177. PBOOL BreakInRequested
  178. );
  179. KSTATUS
  180. KdpSendProfilingData (
  181. PBOOL BreakInRequested
  182. );
  183. USHORT
  184. KdpCalculateChecksum (
  185. PVOID Data,
  186. ULONG DataLength
  187. );
  188. KSTATUS
  189. KdpSendModuleList (
  190. BOOL SendHeaderOnly
  191. );
  192. KSTATUS
  193. KdpHandleMemoryAccess (
  194. VOID
  195. );
  196. VOID
  197. KdpInitializeBreakNotification (
  198. ULONG Exception,
  199. PTRAP_FRAME TrapFrame,
  200. PDEBUG_PACKET Packet
  201. );
  202. VOID
  203. KdpReboot (
  204. DEBUG_REBOOT_TYPE RebootType,
  205. ULONG Exception,
  206. PTRAP_FRAME TrapFrame
  207. );
  208. VOID
  209. KdpDisconnect (
  210. VOID
  211. );
  212. KSTATUS
  213. KdpConnect (
  214. PBOOL BreakInRequested
  215. );
  216. VOID
  217. KdpSynchronize (
  218. VOID
  219. );
  220. KSTATUS
  221. KdpSendConnectionResponse (
  222. PCONNECTION_REQUEST ConnectionRequest,
  223. PBOOL BreakInRequested
  224. );
  225. VOID
  226. KdpInternalPrint (
  227. PSTR Format,
  228. ...
  229. );
  230. VOID
  231. KdpAcquireDebuggerLock (
  232. PTRAP_FRAME TrapFrame
  233. );
  234. VOID
  235. KdpReleaseDebuggerLock (
  236. VOID
  237. );
  238. KSTATUS
  239. KdpTransmitBytes (
  240. PVOID Data,
  241. ULONG Size
  242. );
  243. KSTATUS
  244. KdpReceiveBuffer (
  245. PVOID Data,
  246. PULONG Size,
  247. PULONG Timeout
  248. );
  249. KSTATUS
  250. KdpDeviceReceiveBuffer (
  251. PVOID Data,
  252. PULONG Size,
  253. PULONG Timeout
  254. );
  255. KSTATUS
  256. KdpDeviceReset (
  257. ULONG BaudRate
  258. );
  259. KSTATUS
  260. KdpDeviceTransmit (
  261. PVOID Data,
  262. ULONG Size
  263. );
  264. KSTATUS
  265. KdpDeviceReceive (
  266. PVOID Data,
  267. PULONG Size
  268. );
  269. KSTATUS
  270. KdpDeviceGetStatus (
  271. PBOOL ReceiveDataAvailable
  272. );
  273. VOID
  274. KdpDeviceDisconnect (
  275. VOID
  276. );
  277. VOID
  278. KdpFreezeProcessors (
  279. VOID
  280. );
  281. //
  282. // ------------------------------------------------------------------ Functions
  283. //
  284. KERNEL_API
  285. VOID
  286. KdConnect (
  287. VOID
  288. )
  289. /*++
  290. Routine Description:
  291. This routine connects to the kernel debugger.
  292. Arguments:
  293. None.
  294. Return Value:
  295. None.
  296. --*/
  297. {
  298. if ((KdInitialized == FALSE) || (KdDebuggingEnabled == FALSE)) {
  299. return;
  300. }
  301. RtlDebugService(EXCEPTION_DEBUGGER_CONNECT, NULL);
  302. return;
  303. }
  304. KERNEL_API
  305. VOID
  306. KdDisconnect (
  307. VOID
  308. )
  309. /*++
  310. Routine Description:
  311. This routine disconnects from the kernel debugger.
  312. Arguments:
  313. None.
  314. Return Value:
  315. None.
  316. --*/
  317. {
  318. if ((KdInitialized == FALSE) ||
  319. (KdDebuggingEnabled == FALSE) ||
  320. (KdDebuggerConnected == FALSE)) {
  321. return;
  322. }
  323. RtlDebugService(EXCEPTION_DEBUGGER_DISCONNECT, NULL);
  324. return;
  325. }
  326. KERNEL_API
  327. KSTATUS
  328. KdGetDeviceInformation (
  329. PDEBUG_HANDOFF_DATA *Information
  330. )
  331. /*++
  332. Routine Description:
  333. This routine returns information about the debug device in use. This
  334. includes information identifying the device, OEM-specific data, and
  335. transport-specific data that may be needed to coordinate shared control
  336. between runtime drivers and the kernel debug subsystem.
  337. Arguments:
  338. Information - Supplies a pointer where a pointer to the debug information
  339. will be returned on success. The caller must not modify or free this
  340. data.
  341. Return Value:
  342. STATUS_SUCCESS if information was successfully returned.
  343. STATUS_NO_ELIGIBLE_DEVICES if no debug devices were found or used.
  344. Other status codes on other errors.
  345. --*/
  346. {
  347. KSTATUS Status;
  348. if (Information != NULL) {
  349. *Information = NULL;
  350. }
  351. if (KdDebugDevice == NULL) {
  352. return STATUS_NO_ELIGIBLE_DEVICES;
  353. }
  354. KdHandoffData.PortType = KdDebugDevice->PortType;
  355. KdHandoffData.PortSubType = KdDebugDevice->PortSubType;
  356. KdHandoffData.Identifier = KdDebugDevice->Identifier;
  357. if (KdHandoffData.PortType == DEBUG_PORT_TYPE_USB) {
  358. Status = KdpUsbGetHandoffData(&KdHandoffData);
  359. if (!KSUCCESS(Status)) {
  360. return Status;
  361. }
  362. }
  363. if (Information != NULL) {
  364. *Information = &KdHandoffData;
  365. }
  366. return STATUS_SUCCESS;
  367. }
  368. VOID
  369. KdPrint (
  370. PSTR Format,
  371. ...
  372. )
  373. /*++
  374. Routine Description:
  375. This routine prints a string to the debugger. Currently the maximum length
  376. string is a little less than one debug packet.
  377. Arguments:
  378. Format - Supplies a pointer to the printf-like format string.
  379. ... - Supplies any needed arguments for the format string.
  380. Return Value:
  381. None.
  382. --*/
  383. {
  384. va_list ArgumentList;
  385. va_start(ArgumentList, Format);
  386. KdPrintWithArgumentList(Format, ArgumentList);
  387. va_end(ArgumentList);
  388. return;
  389. }
  390. VOID
  391. KdPrintWithArgumentList (
  392. PSTR Format,
  393. va_list ArgumentList
  394. )
  395. /*++
  396. Routine Description:
  397. This routine prints a string to the debugger. Currently the maximum length
  398. string is a little less than one debug packet.
  399. Arguments:
  400. Format - Supplies a pointer to the printf-like format string.
  401. ArgumentList - Supplies a pointer to the initialized list of arguments
  402. required for the format string.
  403. Return Value:
  404. None.
  405. --*/
  406. {
  407. PRINT_PARAMETERS PrintParameters;
  408. if ((KdDebuggingEnabled != FALSE) &&
  409. (KdDebuggerConnected != FALSE) &&
  410. (KdInitialized != FALSE)) {
  411. PrintParameters.FormatString = Format;
  412. PrintParameters.Arguments = ArgumentList;
  413. RtlDebugService(EXCEPTION_PRINT, &PrintParameters);
  414. }
  415. return;
  416. }
  417. KSTATUS
  418. KdInitialize (
  419. PDEBUG_DEVICE_DESCRIPTION DebugDevice,
  420. PDEBUG_MODULE CurrentModule
  421. )
  422. /*++
  423. Routine Description:
  424. This routine initializes the debugger subsystem and connects to the target
  425. if debugging is enabled.
  426. Arguments:
  427. DebugDevice - Supplies a pointer to the debug device to communicate on.
  428. CurrentModule - Supplies the details of the initial running program.
  429. Return Value:
  430. Kernel status code.
  431. --*/
  432. {
  433. PSTR KernelBinaryName;
  434. PDEBUG_MODULE KernelModule;
  435. ULONG NameSize;
  436. KSTATUS Status;
  437. Status = STATUS_SUCCESS;
  438. if (DebugDevice != NULL) {
  439. KdDebugDevice = DebugDevice;
  440. }
  441. //
  442. // Set up the loaded modules list now if it has not been done.
  443. //
  444. if (KdLoadedModulesInitialized == FALSE) {
  445. KernelModule = (PDEBUG_MODULE)KdKernelModuleBuffer;
  446. KernelBinaryName = CurrentModule->BinaryName;
  447. //
  448. // Copy the name string into the kernel module structure.
  449. //
  450. NameSize = CurrentModule->StructureSize - sizeof(DEBUG_MODULE) +
  451. (ANYSIZE_ARRAY * sizeof(CHAR));
  452. if (NameSize > MAX_KERNEL_MODULE_NAME) {
  453. NameSize = MAX_KERNEL_MODULE_NAME;
  454. }
  455. RtlStringCopy(KernelModule->BinaryName, KernelBinaryName, NameSize);
  456. KernelModule->StructureSize = CurrentModule->StructureSize;
  457. //
  458. // Fill out the rest of the kernel module information.
  459. //
  460. KernelModule->BaseAddress = CurrentModule->BaseAddress;
  461. KernelModule->LowestAddress = CurrentModule->LowestAddress;
  462. KernelModule->Size = CurrentModule->Size;
  463. KernelModule->Timestamp = CurrentModule->Timestamp;
  464. KernelModule->Process = 0;
  465. //
  466. // Initialize the loaded modules list, inserting the kernel as the first
  467. // entry.
  468. //
  469. KdLoadedModules.ModuleCount = 1;
  470. KdLoadedModules.Signature = KernelModule->Timestamp +
  471. (UINTN)(KernelModule->LowestAddress);
  472. INITIALIZE_LIST_HEAD(&(KdLoadedModules.ModulesHead));
  473. INSERT_AFTER(&(KernelModule->ListEntry),
  474. &(KdLoadedModules.ModulesHead));
  475. KdLoadedModulesInitialized = TRUE;
  476. }
  477. //
  478. // Initialize debugging hardware state.
  479. //
  480. KdpInitializeDebuggingHardware();
  481. //
  482. // Initialize other runtime globals.
  483. //
  484. KdBreakRange.Enabled = FALSE;
  485. KdUserRequestedSingleStep = FALSE;
  486. KdInitialized = TRUE;
  487. //
  488. // If debugging is not enabled, then initialization is finished.
  489. //
  490. if (KdDebuggingEnabled == FALSE) {
  491. Status = STATUS_SUCCESS;
  492. goto InitializeEnd;
  493. }
  494. //
  495. // Fire up a connection with the host.
  496. //
  497. KdConnect();
  498. InitializeEnd:
  499. return Status;
  500. }
  501. VOID
  502. KdBreak (
  503. VOID
  504. )
  505. /*++
  506. Routine Description:
  507. This routine breaks into the debugger if one is connected.
  508. Arguments:
  509. None.
  510. Return Value:
  511. Kernel status code.
  512. --*/
  513. {
  514. if ((KdDebuggingEnabled != FALSE) && (KdInitialized != FALSE)) {
  515. KdpBreak();
  516. }
  517. return;
  518. }
  519. VOID
  520. KdReportModuleChange (
  521. PDEBUG_MODULE Module,
  522. BOOL Loading
  523. )
  524. /*++
  525. Routine Description:
  526. This routine informs the debugger of an image being loaded or unloaded.
  527. Arguments:
  528. Module - Supplies a pointer to the module being loaded or unloaded. The
  529. caller is responsible for managing this memory. The memory should
  530. not be freed until after reporting that the module has unloaded. This
  531. memory must not be pagable.
  532. Loading - Supplies a flag indicating whether the module is being loaded or
  533. unloaded.
  534. Return Value:
  535. None.
  536. --*/
  537. {
  538. MODULE_CHANGE_NOTIFICATION Notification;
  539. Notification.Module = Module;
  540. Notification.Loading = Loading;
  541. RtlDebugService(EXCEPTION_MODULE_CHANGE, &Notification);
  542. return;
  543. }
  544. VOID
  545. KdPollForBreakRequest (
  546. VOID
  547. )
  548. /*++
  549. Routine Description:
  550. This routine polls the debugger connection to determine if the debugger
  551. has requested to break in.
  552. Arguments:
  553. None.
  554. Return Value:
  555. None.
  556. --*/
  557. {
  558. //
  559. // If debugging is not enabled, then this shouldn't execute. This does
  560. // run even if the debugger is disconnected in case the debugger is trying
  561. // to connect.
  562. //
  563. if ((KdInitialized == FALSE) || (KdDebuggingEnabled == FALSE)) {
  564. return;
  565. }
  566. RtlDebugService(EXCEPTION_POLL_DEBUGGER, NULL);
  567. return;
  568. }
  569. BOOL
  570. KdIsDebuggerConnected (
  571. VOID
  572. )
  573. /*++
  574. Routine Description:
  575. This routine indicates whether or not a kernel debugger is currently
  576. connected to the system.
  577. Arguments:
  578. None.
  579. Return Value:
  580. TRUE if the debugger is enabled and connected.
  581. FALSE otherwise.
  582. --*/
  583. {
  584. return KdDebuggerConnected;
  585. }
  586. BOOL
  587. KdAreUserModeExceptionsEnabled (
  588. VOID
  589. )
  590. /*++
  591. Routine Description:
  592. This routine indicates whether or not noteworthy exceptions caused in
  593. applications should bubble up to kernel mode debugger breaks.
  594. Arguments:
  595. None.
  596. Return Value:
  597. TRUE if user mode exceptions should bubble up to kernel mode.
  598. FALSE otherwise.
  599. --*/
  600. {
  601. return KdEnableUserModeExceptions;
  602. }
  603. ULONG
  604. KdSetConnectionTimeout (
  605. ULONG Timeout
  606. )
  607. /*++
  608. Routine Description:
  609. This routine sets the debugger connection timeout.
  610. Arguments:
  611. Timeout - Supplies the new timeout in microseconds. Supply MAX_ULONG to
  612. cause the debugger to not call the stall function and never time out
  613. the connection.
  614. Return Value:
  615. Returns the original timeout.
  616. --*/
  617. {
  618. return RtlAtomicExchange32(&KdConnectionTimeout, Timeout);
  619. }
  620. VOID
  621. KdSendProfilingData (
  622. VOID
  623. )
  624. /*++
  625. Routine Description:
  626. This routine polls the system profiler to determine if there is profiling
  627. data to be sent to the debugger.
  628. Arguments:
  629. None.
  630. Return Value:
  631. None.
  632. --*/
  633. {
  634. ULONG Flags;
  635. //
  636. // If debugging is not enabled, then this shouldn't execute.
  637. //
  638. if ((KdInitialized == FALSE) || (KdDebuggingEnabled == FALSE)) {
  639. return;
  640. }
  641. //
  642. // If the debugger's not actually connected, just poll for a connection
  643. // request.
  644. //
  645. Flags = 0;
  646. if (KdDebuggerConnected != FALSE) {
  647. Flags = SpGetProfilerDataStatus();
  648. }
  649. if (Flags == 0) {
  650. KdPollForBreakRequest();
  651. } else {
  652. RtlDebugService(EXCEPTION_PROFILER, NULL);
  653. }
  654. return;
  655. }
  656. VOID
  657. KdEnableNmiBroadcast (
  658. BOOL Enable
  659. )
  660. /*++
  661. Routine Description:
  662. This routine enables or disables the use of NMI broadcasts by the debugger.
  663. Arguments:
  664. Enable - Supplies TRUE if NMI broadcast is being enabled, or FALSE if NMI
  665. broadcast is being disabled.
  666. Return Value:
  667. None.
  668. --*/
  669. {
  670. KdNmiBroadcastAllowed = Enable;
  671. return;
  672. }
  673. VOID
  674. KdDebugExceptionHandler (
  675. ULONG Exception,
  676. PVOID Parameter,
  677. PTRAP_FRAME TrapFrame
  678. )
  679. /*++
  680. Routine Description:
  681. This routine handles the debug break exception. It is usually called by an
  682. assembly routine responding to an exception.
  683. Arguments:
  684. Exception - Supplies the type of exception that this function is handling.
  685. See EXCEPTION_* definitions for valid values.
  686. Parameter - Supplies a pointer to a parameter supplying additional
  687. context in the case of a debug service request.
  688. TrapFrame - Supplies a pointer to the state of the machine immediately
  689. before the debug exception occurred. Also returns the possibly modified
  690. machine state.
  691. Return Value:
  692. None.
  693. --*/
  694. {
  695. BOOL BreakInRequested;
  696. BOOL ContinueExecution;
  697. ULONG FreezeOwner;
  698. BOOL FunctionReturning;
  699. BOOL InsideRange;
  700. ULONGLONG InstructionPointer;
  701. PMODULE_CHANGE_NOTIFICATION Notification;
  702. BOOL OutsideHole;
  703. PVOID PreviousSingleStepAddress;
  704. PPROCESSOR_BLOCK ProcessorBlock;
  705. BOOL ReceiveDataAvailable;
  706. BOOL SingleStepHandled;
  707. KSTATUS Status;
  708. BreakInRequested = FALSE;
  709. PreviousSingleStepAddress = NULL;
  710. ProcessorBlock = NULL;
  711. SingleStepHandled = FALSE;
  712. KD_TRACE(KdTraceInExceptionHandler);
  713. //
  714. // If debugging is not enabled, then this shouldn't execute.
  715. //
  716. if ((KdInitialized == FALSE) || (KdDebuggingEnabled == FALSE)) {
  717. return;
  718. }
  719. KD_TRACE(KdTraceDebuggingEnabled);
  720. //
  721. // If the exception is a user mode trap, use the trap frame provided by the
  722. // parameter and treat it as a single step.
  723. //
  724. if (Exception == EXCEPTION_USER_MODE) {
  725. TrapFrame = (PTRAP_FRAME)Parameter;
  726. Exception = EXCEPTION_BREAK;
  727. }
  728. //
  729. // Disable interrupts. They will get re-enabled by popping flags on the
  730. // return from this exception. Also acquire the lock so that two processors
  731. // aren't using the debug port at once.
  732. //
  733. KdpDisableInterrupts();
  734. KdpAcquireDebuggerLock(TrapFrame);
  735. KdpAtomicAdd32(&KdProcessorsFrozen, 1);
  736. KD_TRACE(KdTraceLockAcquired);
  737. //
  738. // If this is just a poll, check for received bytes before bothering to
  739. // freeze everyone. Chances are there's nothing.
  740. //
  741. if (Exception == EXCEPTION_POLL_DEBUGGER) {
  742. Status = KdpDeviceGetStatus(&ReceiveDataAvailable);
  743. if ((!KSUCCESS(Status)) || (ReceiveDataAvailable == FALSE)) {
  744. KD_TRACE(KdTracePollBailing);
  745. goto DebugExceptionHandlerEnd;
  746. }
  747. }
  748. //
  749. // Clear single step mode super early to minimize the chance of infinite
  750. // breakpoints if using a software-based single step mechanism. Remember to
  751. // put it back if this routine shortcuts to the exit.
  752. //
  753. KdpClearSingleStepMode(&Exception, TrapFrame, &PreviousSingleStepAddress);
  754. KD_TRACE(KdTraceClearedSingleStep);
  755. if (KeActiveProcessorCount > 1) {
  756. ProcessorBlock = KeGetCurrentProcessorBlockForDebugger();
  757. if (KdNmiBroadcastAllowed != FALSE) {
  758. FreezeOwner = KdpAtomicCompareExchange32(
  759. &KdFreezeOwner,
  760. ProcessorBlock->ProcessorNumber,
  761. MAX_ULONG);
  762. if (FreezeOwner != MAX_ULONG) {
  763. KdpReleaseDebuggerLock();
  764. KD_ASSERT_ONCE(FALSE);
  765. KdpAcquireDebuggerLock(TrapFrame);
  766. }
  767. //
  768. // Send an NMI to freeze all other processors, and wait until all
  769. // processors are frozen. Skip this when sending profiling data to
  770. // allow higher throughput.
  771. //
  772. if (Exception != EXCEPTION_PROFILER) {
  773. KdpFreezeProcessors();
  774. }
  775. //
  776. // There are more than one processors, but for whatever reason the
  777. // debugger should not be trying to freeze them. Set the freeze owner
  778. // to the current processor so it acts like the owner.
  779. //
  780. } else {
  781. KdFreezeOwner = ProcessorBlock->ProcessorNumber;
  782. }
  783. //
  784. // If there's only one processor, don't even get the processor block
  785. // (as it may not be there), just set the freeze owner.
  786. //
  787. } else {
  788. KdFreezeOwner = 0;
  789. }
  790. KD_TRACE(KdTraceProcessorsFrozen);
  791. //
  792. // If the exception is a result of polling, find out what's being sent.
  793. // Process this possible exception first because it's super common.
  794. //
  795. if (Exception == EXCEPTION_POLL_DEBUGGER) {
  796. while (TRUE) {
  797. Status = KdpDeviceGetStatus(&ReceiveDataAvailable);
  798. if ((!KSUCCESS(Status)) || (ReceiveDataAvailable == FALSE)) {
  799. KD_TRACE(KdTracePollBailing);
  800. break;
  801. }
  802. Status = KdpReceivePacket(&KdRxPacket, KdConnectionTimeout);
  803. if (!KSUCCESS(Status)) {
  804. KD_TRACE(KdTraceReceiveFailure);
  805. if (Status == STATUS_CONNECTION_RESET) {
  806. Exception = EXCEPTION_DEBUGGER_CONNECT;
  807. }
  808. break;
  809. }
  810. KD_TRACE(KdTraceProcessingCommand);
  811. if (KdRxPacket.Header.Command == DbgBreakRequest) {
  812. Exception = EXCEPTION_BREAK;
  813. KdDebuggerConnected = TRUE;
  814. } else {
  815. ContinueExecution = FALSE;
  816. Status = KdpProcessCommand(&KdRxPacket,
  817. Exception,
  818. TrapFrame,
  819. &ContinueExecution);
  820. if (!KSUCCESS(Status)) {
  821. break;
  822. }
  823. if (ContinueExecution == FALSE) {
  824. Exception = EXCEPTION_BREAK;
  825. }
  826. }
  827. }
  828. if (Exception == EXCEPTION_POLL_DEBUGGER) {
  829. goto DebugExceptionHandlerEnd;
  830. }
  831. //
  832. // If the exception was a disconnect request, do the disconnect and return.
  833. //
  834. } else if (Exception == EXCEPTION_DEBUGGER_DISCONNECT) {
  835. KdpDisconnect();
  836. goto DebugExceptionHandlerEnd;
  837. //
  838. // If the exception was just a print, do the print and return.
  839. //
  840. } else if (Exception == EXCEPTION_PRINT) {
  841. KD_TRACE(KdTracePrinting);
  842. KdpPrint((PPRINT_PARAMETERS)Parameter, &BreakInRequested);
  843. if (BreakInRequested == FALSE) {
  844. goto DebugExceptionHandlerEnd;
  845. }
  846. Exception = EXCEPTION_BREAK;
  847. //
  848. // If the exception is just to send profiling data, send the data and
  849. // return.
  850. //
  851. } else if (Exception == EXCEPTION_PROFILER) {
  852. KD_TRACE(KdTraceSendingProfilingData);
  853. KdpSendProfilingData(&BreakInRequested);
  854. if (BreakInRequested == FALSE) {
  855. goto DebugExceptionHandlerEnd;
  856. }
  857. //
  858. // The other cores were not frozen above. Attempt to freeze them now
  859. // that the debugger needs break in.
  860. //
  861. KdpFreezeProcessors();
  862. Exception = EXCEPTION_BREAK;
  863. //
  864. // If the exception was a module state change, update the module
  865. // information and return.
  866. //
  867. } else if (Exception == EXCEPTION_MODULE_CHANGE) {
  868. KD_TRACE(KdTraceModuleChange);
  869. Notification = (PMODULE_CHANGE_NOTIFICATION)Parameter;
  870. if (Notification->Loading == FALSE) {
  871. KdLoadedModules.ModuleCount -= 1;
  872. KdLoadedModules.Signature -=
  873. Notification->Module->Timestamp +
  874. (UINTN)(Notification->Module->LowestAddress);
  875. LIST_REMOVE(&(Notification->Module->ListEntry));
  876. } else {
  877. KdLoadedModules.ModuleCount += 1;
  878. KdLoadedModules.Signature +=
  879. Notification->Module->Timestamp +
  880. (UINTN)(Notification->Module->LowestAddress);
  881. INSERT_AFTER(&(Notification->Module->ListEntry),
  882. &(KdLoadedModules.ModulesHead));
  883. }
  884. goto DebugExceptionHandlerEnd;
  885. }
  886. //
  887. // If the exception is a connection request or one of the above exceptions
  888. // noticed that the host needed to be reconnected, run through the
  889. // connection process.
  890. //
  891. if (Exception == EXCEPTION_DEBUGGER_CONNECT) {
  892. KD_TRACE(KdTraceConnecting);
  893. Status = KdpConnect(&BreakInRequested);
  894. if ((KSUCCESS(Status)) && (BreakInRequested != FALSE)) {
  895. Exception = EXCEPTION_BREAK;
  896. } else {
  897. KD_TRACE(KdTraceConnectBailing);
  898. goto DebugExceptionHandlerEnd;
  899. }
  900. }
  901. KD_TRACE(KdTraceCheckSingleStep);
  902. //
  903. // There are no more shortcuts out of this function, this is going to make
  904. // it to the user. Don't feel responsible for restoring the cleared single
  905. // step, as the remainder of the routine will decide whether or not to set
  906. // a new one.
  907. //
  908. PreviousSingleStepAddress = NULL;
  909. //
  910. // If the user requested this single step or this is not a single step,
  911. // cancel the range breakpoint.
  912. //
  913. if ((KdUserRequestedSingleStep != FALSE) ||
  914. (Exception != EXCEPTION_SINGLE_STEP)) {
  915. KdBreakRange.Enabled = FALSE;
  916. }
  917. //
  918. // If the range breakpoint is active and the user didn't request a single
  919. // step, then the only purpose of this step is to validate the break range.
  920. //
  921. InstructionPointer = (UINTN)KdpGetInstructionPointer(TrapFrame);
  922. if ((KdBreakRange.Enabled != FALSE) &&
  923. (Exception == EXCEPTION_SINGLE_STEP)) {
  924. InsideRange =
  925. (InstructionPointer >= (ULONG)KdBreakRange.BreakRangeStart) &&
  926. (InstructionPointer < (ULONG)KdBreakRange.BreakRangeEnd);
  927. OutsideHole =
  928. (InstructionPointer < (ULONG)KdBreakRange.RangeHoleStart) ||
  929. (InstructionPointer >= (ULONG)KdBreakRange.RangeHoleEnd);
  930. if ((OutsideHole != FALSE) && (InsideRange != FALSE)) {
  931. //
  932. // This instruction fits the range description. Change the exception
  933. // to a break and turn off the trap flag. This turns it into a real
  934. // exception that will notify the debugger.
  935. //
  936. Exception = EXCEPTION_BREAK;
  937. //
  938. // This instruction does not fit the range. Continue single stepping.
  939. //
  940. } else {
  941. KdpSetSingleStepMode(Exception, TrapFrame, NULL);
  942. SingleStepHandled = TRUE;
  943. KdPeriodicBreakInCheck += 1;
  944. if ((KdPeriodicBreakInCheck &
  945. DEBUG_PERIODIC_BREAK_CHECK_MASK) == 0) {
  946. Status = KdpDeviceGetStatus(&ReceiveDataAvailable);
  947. if ((KSUCCESS(Status)) || (ReceiveDataAvailable != FALSE)) {
  948. SingleStepHandled = FALSE;
  949. }
  950. }
  951. //
  952. // If this instruction is a function return, check to see if it
  953. // matches the range (but is in the hole). If so, expand the range
  954. // to the whole address range so the next step won't miss the fact
  955. // that the function just returned.
  956. //
  957. FunctionReturning = KdpIsFunctionReturning(TrapFrame);
  958. if ((InsideRange != FALSE) && (FunctionReturning != FALSE)) {
  959. KdBreakRange.BreakRangeStart = 0;
  960. KdBreakRange.BreakRangeEnd = (PVOID)MAX_ULONG;
  961. }
  962. }
  963. }
  964. //
  965. // If the user did not request a single step exception, and it was handled
  966. // above, then there is no reason to communicate with the debugger.
  967. //
  968. if ((Exception == EXCEPTION_SINGLE_STEP) &&
  969. (SingleStepHandled != FALSE)) {
  970. goto DebugExceptionHandlerEnd;
  971. }
  972. KD_TRACE(KdTraceCommittingToBreak);
  973. //
  974. // Unless it isn't connected, this break is going to make it to the
  975. // debugger. Turn off the break range.
  976. //
  977. KdBreakRange.Enabled = FALSE;
  978. //
  979. // Now that essential business is taken care of, check to see if there's a
  980. // debugger to talk to. If not, return.
  981. //
  982. if (KdDebuggerConnected == FALSE) {
  983. KD_TRACE(KdTraceBailingUnconnected);
  984. goto DebugExceptionHandlerEnd;
  985. }
  986. while (TRUE) {
  987. if (KdFreezeOwner == MAX_ULONG) {
  988. break;
  989. }
  990. if ((KeActiveProcessorCount > 1) &&
  991. (KdFreezeOwner != ProcessorBlock->ProcessorNumber)) {
  992. continue;
  993. }
  994. //
  995. // Loop processing commands and handling connection resets. Also send a
  996. // break request the first time around the loop and if the connection
  997. // was reset.
  998. //
  999. BreakInRequested = TRUE;
  1000. KD_TRACE(KdTraceProcessingCommand);
  1001. ContinueExecution = FALSE;
  1002. do {
  1003. if (BreakInRequested != FALSE) {
  1004. KdpInitializeBreakNotification(Exception,
  1005. TrapFrame,
  1006. &KdTxPacket);
  1007. Status = KdpSendPacket(&KdTxPacket, NULL);
  1008. if (!KSUCCESS(Status)) {
  1009. KD_TRACE(KdTraceTransmitFailure);
  1010. goto DebugExceptionHandlerEnd;
  1011. }
  1012. BreakInRequested = FALSE;
  1013. }
  1014. Status = KdpReceivePacket(&KdRxPacket, MAX_ULONG);
  1015. if (!KSUCCESS(Status)) {
  1016. continue;
  1017. }
  1018. Status = KdpProcessCommand(&KdRxPacket,
  1019. Exception,
  1020. TrapFrame,
  1021. &ContinueExecution);
  1022. if (!KSUCCESS(Status)) {
  1023. break;
  1024. }
  1025. } while (ContinueExecution == FALSE);
  1026. }
  1027. DebugExceptionHandlerEnd:
  1028. KD_TRACE(KdTraceThawingProcessors);
  1029. if (PreviousSingleStepAddress != NULL) {
  1030. KdpSetSingleStepMode(Exception, TrapFrame, PreviousSingleStepAddress);
  1031. }
  1032. KdpAtomicCompareExchange32(&KdFreezeOwner, MAX_ULONG, KdFreezeOwner);
  1033. //
  1034. // Wait until all processors are ready to go, then go.
  1035. //
  1036. KdpAtomicAdd32(&KdProcessorsFrozen, -1);
  1037. while (KdProcessorsFrozen != 0) {
  1038. NOTHING;
  1039. }
  1040. KdpReleaseDebuggerLock();
  1041. KD_TRACE(KdTraceExit);
  1042. return;
  1043. }
  1044. VOID
  1045. KdNmiHandler (
  1046. PTRAP_FRAME TrapFrame
  1047. )
  1048. /*++
  1049. Routine Description:
  1050. This routine handles NMI interrupts.
  1051. Arguments:
  1052. TrapFrame - Supplies a pointer to the state of the machine immediately
  1053. before the NMI occurred. Also returns the possibly modified
  1054. machine state.
  1055. Return Value:
  1056. None.
  1057. --*/
  1058. {
  1059. BOOL ContinueExecution;
  1060. PPROCESSOR_BLOCK ProcessorBlock;
  1061. KSTATUS Status;
  1062. KdpDisableInterrupts();
  1063. ProcessorBlock = KeGetCurrentProcessorBlockForDebugger();
  1064. //
  1065. // If there is no freeze owner or no processors are frozen, this may be a
  1066. // real NMI. Crash here unless NMIs are maskable.
  1067. //
  1068. if ((KdFreezeOwner == MAX_ULONG) ||
  1069. (KdProcessorsFrozen == 0) ||
  1070. (KdProcessorsFrozen >= KeActiveProcessorCount)) {
  1071. ASSERT(KdFreezesAreMaskable != FALSE);
  1072. return;
  1073. }
  1074. //
  1075. // Let the freeze owner know that this processor is frozen and listening.
  1076. //
  1077. KdpAtomicAdd32(&KdProcessorsFrozen, 1);
  1078. //
  1079. // Spin waiting for the freeze owner to become this processor or signal to
  1080. // continue execution.
  1081. //
  1082. while (TRUE) {
  1083. //
  1084. // If the freeze owner becomes -1, break out and continue execution.
  1085. //
  1086. if (KdFreezeOwner == MAX_ULONG) {
  1087. break;
  1088. }
  1089. //
  1090. // If the freeze owner becomes this processor, take over and start
  1091. // processing commands. Report this as a regular break exception to
  1092. // distinguish between actual NMIs and debug IPIs.
  1093. //
  1094. if (KdFreezeOwner == ProcessorBlock->ProcessorNumber) {
  1095. KdpInitializeBreakNotification(EXCEPTION_BREAK,
  1096. TrapFrame,
  1097. &KdTxPacket);
  1098. Status = KdpSendPacket(&KdTxPacket, NULL);
  1099. if (!KSUCCESS(Status)) {
  1100. continue;
  1101. }
  1102. //
  1103. // Loop processing commands.
  1104. //
  1105. ContinueExecution = FALSE;
  1106. do {
  1107. Status = KdpReceivePacket(&KdRxPacket, MAX_ULONG);
  1108. if (!KSUCCESS(Status)) {
  1109. continue;
  1110. }
  1111. Status = KdpProcessCommand(&KdRxPacket,
  1112. EXCEPTION_NMI,
  1113. TrapFrame,
  1114. &ContinueExecution);
  1115. if (!KSUCCESS(Status)) {
  1116. break;
  1117. }
  1118. } while (ContinueExecution == FALSE);
  1119. }
  1120. }
  1121. KdpInvalidateInstructionCache();
  1122. //
  1123. // Indicate that this processor is back on its way, and go.
  1124. //
  1125. KdpAtomicAdd32(&KdProcessorsFrozen, -1);
  1126. return;
  1127. }
  1128. //
  1129. // --------------------------------------------------------- Internal Functions
  1130. //
  1131. KSTATUS
  1132. KdpSendPacket (
  1133. PDEBUG_PACKET Packet,
  1134. PBOOL BreakInRequested
  1135. )
  1136. /*++
  1137. Routine Description:
  1138. This routine sends a packet across the wire to the debugging client.
  1139. Arguments:
  1140. Packet - Supplies a pointer to the debug packet. The checksum field will be
  1141. calculated in this function.
  1142. BreakInRequested - Supplies an optional pointer where a boolean will be
  1143. returned indicating if the debugger would like to break in.
  1144. Return Value:
  1145. Status code.
  1146. --*/
  1147. {
  1148. DEBUG_PACKET_ACKNOWLEDGE Acknowledge;
  1149. USHORT Checksum;
  1150. DEBUG_PACKET_HEADER Header;
  1151. ULONG HeaderSize;
  1152. ULONG PayloadSize;
  1153. ULONG Retries;
  1154. KSTATUS Status;
  1155. ULONG Timeout;
  1156. HeaderSize = sizeof(DEBUG_PACKET_HEADER);
  1157. if (BreakInRequested != NULL) {
  1158. *BreakInRequested = FALSE;
  1159. }
  1160. if ((KdInitialized == FALSE) || (KdDebuggingEnabled == FALSE)) {
  1161. return STATUS_NOT_INITIALIZED;
  1162. }
  1163. if (Packet->Header.PayloadSize > DEBUG_PACKET_SIZE - HeaderSize) {
  1164. return STATUS_INVALID_PARAMETER;
  1165. }
  1166. Packet->Header.Magic = DEBUG_PACKET_MAGIC;
  1167. Packet->Header.PayloadSizeComplement = ~(Packet->Header.PayloadSize);
  1168. Packet->Header.Checksum = 0;
  1169. Checksum = KdpCalculateChecksum(Packet,
  1170. Packet->Header.PayloadSize + HeaderSize);
  1171. Packet->Header.Checksum = Checksum;
  1172. //
  1173. // Loop sending the data until an ackowledgement or rejection is received.
  1174. //
  1175. Timeout = KdConnectionTimeout;
  1176. Retries = 10;
  1177. while (Retries > 0) {
  1178. Status = KdpTransmitBytes(Packet,
  1179. HeaderSize + Packet->Header.PayloadSize);
  1180. if (!KSUCCESS(Status)) {
  1181. Retries -= 1;
  1182. continue;
  1183. }
  1184. Status = KdpReceivePacketHeader(&Header, &Timeout);
  1185. if ((Status == STATUS_TIMEOUT) || (Status == STATUS_CONNECTION_RESET)) {
  1186. break;
  1187. }
  1188. if (!KSUCCESS(Status)) {
  1189. Retries -= 1;
  1190. continue;
  1191. }
  1192. if (Header.Command == DbgPacketAcknowledge) {
  1193. //
  1194. // Attempt to read the payload, which says whether or not the
  1195. // debugger would like to break in.
  1196. //
  1197. if (Header.PayloadSize == sizeof(DEBUG_PACKET_ACKNOWLEDGE)) {
  1198. PayloadSize = sizeof(DEBUG_PACKET_ACKNOWLEDGE);
  1199. Status = KdpReceiveBuffer(&Acknowledge, &PayloadSize, &Timeout);
  1200. if ((KSUCCESS(Status)) && (BreakInRequested != NULL)) {
  1201. *BreakInRequested = Acknowledge.BreakInRequested;
  1202. }
  1203. }
  1204. Status = STATUS_SUCCESS;
  1205. break;
  1206. } else if (Header.Command != DbgPacketResend) {
  1207. Status = STATUS_CONNECTION_RESET;
  1208. break;
  1209. }
  1210. Retries -= 1;
  1211. }
  1212. //
  1213. // If the receive timed out or the connection was reset, mark the
  1214. // connection terminated. Don't send sync bytes if not connected, as that's
  1215. // counterproductive during connect.
  1216. //
  1217. if ((Status == STATUS_TIMEOUT) || (Status == STATUS_CONNECTION_RESET)) {
  1218. if (KdDebuggerConnected != FALSE) {
  1219. KdpSynchronize();
  1220. KdDebuggerConnected = FALSE;
  1221. }
  1222. }
  1223. return Status;
  1224. }
  1225. KSTATUS
  1226. KdpReceivePacket (
  1227. PDEBUG_PACKET Packet,
  1228. ULONG Timeout
  1229. )
  1230. /*++
  1231. Routine Description:
  1232. This routine receives a packet across the wire from the debugger.
  1233. Arguments:
  1234. Packet - Supplies a pointer to the buffer that will receive the debug
  1235. packet.
  1236. Timeout - Supplies the timeout in microseconds that this function should
  1237. give up in.
  1238. Return Value:
  1239. Status code.
  1240. --*/
  1241. {
  1242. DEBUG_PACKET_HEADER Acknowledge;
  1243. USHORT CalculatedChecksum;
  1244. USHORT Checksum;
  1245. USHORT HeaderChecksum;
  1246. ULONG HeaderSize;
  1247. ULONG PayloadSize;
  1248. ULONG Retries;
  1249. KSTATUS Status;
  1250. HeaderSize = sizeof(DEBUG_PACKET_HEADER);
  1251. Retries = 10;
  1252. while (TRUE) {
  1253. Status = KdpReceivePacketHeader(&(Packet->Header), &Timeout);
  1254. if ((Status == STATUS_TIMEOUT) || (Status == STATUS_CONNECTION_RESET)) {
  1255. break;
  1256. }
  1257. if (!KSUCCESS(Status)) {
  1258. goto ReceivePacketRetry;
  1259. }
  1260. //
  1261. // If the packet has a payload, get that as well.
  1262. //
  1263. if (Packet->Header.PayloadSize != 0) {
  1264. PayloadSize = Packet->Header.PayloadSize;
  1265. Status = KdpReceiveBuffer(&(Packet->Payload),
  1266. &PayloadSize,
  1267. &Timeout);
  1268. if (!KSUCCESS(Status)) {
  1269. if (Status == STATUS_TIMEOUT) {
  1270. break;
  1271. }
  1272. goto ReceivePacketRetry;
  1273. }
  1274. }
  1275. //
  1276. // Ensure that the packet came across okay. The checksum field is not
  1277. // included in the checksum calculation, so zero it out while
  1278. // calculating.
  1279. //
  1280. HeaderChecksum = Packet->Header.Checksum;
  1281. Packet->Header.Checksum = 0;
  1282. CalculatedChecksum = KdpCalculateChecksum(
  1283. Packet,
  1284. HeaderSize + Packet->Header.PayloadSize);
  1285. Packet->Header.Checksum = HeaderChecksum;
  1286. if (HeaderChecksum != CalculatedChecksum) {
  1287. Status = STATUS_CHECKSUM_MISMATCH;
  1288. goto ReceivePacketRetry;
  1289. }
  1290. //
  1291. // Send the acknowledge and break.
  1292. //
  1293. RtlZeroMemory(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  1294. Acknowledge.Magic = DEBUG_PACKET_MAGIC;
  1295. Acknowledge.Command = DbgPacketAcknowledge;
  1296. Acknowledge.PayloadSizeComplement = ~(Acknowledge.PayloadSize);
  1297. Checksum = KdpCalculateChecksum(&Acknowledge,
  1298. sizeof(DEBUG_PACKET_HEADER));
  1299. Acknowledge.Checksum = Checksum;
  1300. Status = KdpTransmitBytes(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  1301. if (!KSUCCESS(Status)) {
  1302. goto ReceivePacketRetry;
  1303. }
  1304. Status = STATUS_SUCCESS;
  1305. break;
  1306. ReceivePacketRetry:
  1307. if (Retries == 0) {
  1308. break;
  1309. }
  1310. //
  1311. // Ask the host to resend and loop.
  1312. //
  1313. RtlZeroMemory(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  1314. Acknowledge.Command = DbgPacketResend;
  1315. Acknowledge.PayloadSizeComplement = ~(Acknowledge.PayloadSize);
  1316. Checksum = KdpCalculateChecksum(&Acknowledge,
  1317. sizeof(DEBUG_PACKET_HEADER));
  1318. Acknowledge.Checksum = Checksum;
  1319. Status = KdpTransmitBytes(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  1320. if (!KSUCCESS(Status)) {
  1321. break;
  1322. }
  1323. Retries -= 1;
  1324. }
  1325. //
  1326. // If the receive timed out or the connection was reset, mark the
  1327. // connection terminated. Don't send sync bytes if not connected, as that's
  1328. // counterproductive during connect.
  1329. //
  1330. if ((Status == STATUS_TIMEOUT) || (Status == STATUS_CONNECTION_RESET)) {
  1331. if (KdDebuggerConnected != FALSE) {
  1332. KdpSynchronize();
  1333. KdDebuggerConnected = FALSE;
  1334. }
  1335. }
  1336. return Status;
  1337. }
  1338. KSTATUS
  1339. KdpReceivePacketHeader (
  1340. PDEBUG_PACKET_HEADER Packet,
  1341. PULONG Timeout
  1342. )
  1343. /*++
  1344. Routine Description:
  1345. This routine receives a packet header across the wire from the debugger.
  1346. Arguments:
  1347. Packet - Supplies a pointer to the buffer that will receive the debug
  1348. packet header.
  1349. Timeout - Supplies a pointer that on input contains the number of
  1350. microseconds to wait before timing out. On output, will contain the
  1351. remainder of that wait.
  1352. Return Value:
  1353. Status code.
  1354. --*/
  1355. {
  1356. DEBUG_PACKET_HEADER Acknowledge;
  1357. USHORT Checksum;
  1358. ULONG HeaderSize;
  1359. BYTE Magic;
  1360. PBYTE ReceiveBuffer;
  1361. ULONG ReceiveSize;
  1362. ULONG Retries;
  1363. KSTATUS Status;
  1364. HeaderSize = sizeof(DEBUG_PACKET_HEADER);
  1365. Retries = 10;
  1366. Status = STATUS_SUCCESS;
  1367. while (TRUE) {
  1368. //
  1369. // Attempt to synchronize on the magic field.
  1370. //
  1371. Magic = 0;
  1372. ReceiveSize = sizeof(BYTE);
  1373. Status = KdpReceiveBuffer(&Magic, &ReceiveSize, Timeout);
  1374. if (Status == STATUS_TIMEOUT) {
  1375. break;
  1376. }
  1377. if (!KSUCCESS(Status)) {
  1378. goto ReceivePacketRetry;
  1379. }
  1380. if (Magic != DEBUG_PACKET_MAGIC_BYTE1) {
  1381. //
  1382. // If this was a resync byte from the host, then report the
  1383. // connection as reset.
  1384. //
  1385. if (Magic == DEBUG_SYNCHRONIZE_HOST) {
  1386. Status = STATUS_CONNECTION_RESET;
  1387. break;
  1388. }
  1389. continue;
  1390. }
  1391. Magic = 0;
  1392. ReceiveSize = sizeof(BYTE);
  1393. Status = KdpReceiveBuffer(&Magic, &ReceiveSize, Timeout);
  1394. if (Status == STATUS_TIMEOUT) {
  1395. break;
  1396. }
  1397. if (!KSUCCESS(Status)) {
  1398. goto ReceivePacketRetry;
  1399. }
  1400. if (Magic != DEBUG_PACKET_MAGIC_BYTE2) {
  1401. continue;
  1402. }
  1403. //
  1404. // Get the packet header. Sometimes this is all that's required.
  1405. //
  1406. Packet->Magic = DEBUG_PACKET_MAGIC;
  1407. ReceiveSize = HeaderSize - DEBUG_PACKET_MAGIC_SIZE;
  1408. ReceiveBuffer = (PBYTE)Packet + DEBUG_PACKET_MAGIC_SIZE;
  1409. Status = KdpReceiveBuffer(ReceiveBuffer, &ReceiveSize, Timeout);
  1410. if (!KSUCCESS(Status)) {
  1411. goto ReceivePacketRetry;
  1412. }
  1413. //
  1414. // Validate that the payload size is reasonable by checking its
  1415. // complement against the header.
  1416. //
  1417. if ((USHORT)~(Packet->PayloadSize) != Packet->PayloadSizeComplement) {
  1418. continue;
  1419. }
  1420. if (Packet->PayloadSize > DEBUG_PACKET_SIZE - HeaderSize) {
  1421. Status = STATUS_INVALID_PARAMETER;
  1422. goto ReceivePacketRetry;
  1423. }
  1424. Status = STATUS_SUCCESS;
  1425. break;
  1426. ReceivePacketRetry:
  1427. if (Retries == 0) {
  1428. break;
  1429. }
  1430. //
  1431. // Ask the host to resend and loop.
  1432. //
  1433. RtlZeroMemory(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  1434. Acknowledge.Command = DbgPacketResend;
  1435. Acknowledge.PayloadSizeComplement = ~(Acknowledge.PayloadSize);
  1436. Checksum = KdpCalculateChecksum(&Acknowledge,
  1437. sizeof(DEBUG_PACKET_HEADER));
  1438. Acknowledge.Checksum = Checksum;
  1439. Status = KdpTransmitBytes(&Acknowledge, sizeof(DEBUG_PACKET_HEADER));
  1440. if (!KSUCCESS(Status)) {
  1441. break;
  1442. }
  1443. Retries -= 1;
  1444. }
  1445. return Status;
  1446. }
  1447. KSTATUS
  1448. KdpProcessCommand (
  1449. PDEBUG_PACKET Packet,
  1450. ULONG Exception,
  1451. PTRAP_FRAME TrapFrame,
  1452. PBOOL ContinueExecution
  1453. )
  1454. /*++
  1455. Routine Description:
  1456. This routine processes a received debug packet.
  1457. Arguments:
  1458. Packet - Supplies a pointer to the complete packet.
  1459. Exception - Supplies the exception that caused the break.
  1460. TrapFrame - Supplies a pointer to the machine's current context.
  1461. ContinueExecution - Supplies a pointer that receives whether or not the
  1462. debugger should continue execution or process more packets.
  1463. Return Value:
  1464. Status code.
  1465. --*/
  1466. {
  1467. BOOL BreakInRequested;
  1468. PRANGE_STEP RangeStep;
  1469. PDEBUG_REBOOT_REQUEST RebootRequest;
  1470. PSET_SPECIAL_REGISTERS SetSpecialRegisters;
  1471. KSTATUS Status;
  1472. PSWITCH_PROCESSOR_REQUEST SwitchProcessorRequest;
  1473. Status = STATUS_SUCCESS;
  1474. //
  1475. // By default, most commands don't result in continued execution.
  1476. //
  1477. *ContinueExecution = FALSE;
  1478. switch (KdRxPacket.Header.Command) {
  1479. //
  1480. // Re-send the break notification if needed.
  1481. //
  1482. case DbgBreakRequest:
  1483. KdpInitializeBreakNotification(Exception,
  1484. TrapFrame,
  1485. &KdTxPacket);
  1486. Status = KdpSendPacket(&KdTxPacket, NULL);
  1487. break;
  1488. //
  1489. // The "go" command continues execution. Turn single stepping off in this
  1490. // case.
  1491. //
  1492. case DbgCommandGo:
  1493. KdUserRequestedSingleStep = FALSE;
  1494. //
  1495. // Signal to the caller to break out of the command processing loop,
  1496. // and signal to all other processors to continue execution.
  1497. //
  1498. *ContinueExecution = TRUE;
  1499. KdFreezeOwner = MAX_ULONG;
  1500. break;
  1501. //
  1502. // The single step command is like "go", but turns on the trap flag so that
  1503. // the next instruction to execute will also break into the debugger.
  1504. //
  1505. case DbgCommandSingleStep:
  1506. KdpSetSingleStepMode(Exception, TrapFrame, NULL);
  1507. KdUserRequestedSingleStep = TRUE;
  1508. *ContinueExecution = TRUE;
  1509. KdFreezeOwner = MAX_ULONG;
  1510. break;
  1511. //
  1512. // The range step command puts the machine into single step mode. At every
  1513. // single step, it checks to see if the instruction pointer is within a
  1514. // certain range, and breaks if so.
  1515. //
  1516. case DbgCommandRangeStep:
  1517. RangeStep = (PRANGE_STEP)Packet->Payload;
  1518. KdBreakRange.BreakRangeStart =
  1519. (PVOID)(ULONG)RangeStep->BreakRangeMinimum;
  1520. KdBreakRange.BreakRangeEnd = (PVOID)(ULONG)RangeStep->BreakRangeMaximum;
  1521. KdBreakRange.RangeHoleStart = (PVOID)(ULONG)RangeStep->RangeHoleMinimum;
  1522. KdBreakRange.RangeHoleEnd = (PVOID)(ULONG)RangeStep->RangeHoleMaximum;
  1523. KdBreakRange.Enabled = TRUE;
  1524. KdUserRequestedSingleStep = FALSE;
  1525. KdpSetSingleStepMode(Exception, TrapFrame, NULL);
  1526. *ContinueExecution = TRUE;
  1527. KdFreezeOwner = MAX_ULONG;
  1528. break;
  1529. //
  1530. // The set registers command replaces all the general registers in the trap
  1531. // frame with the ones provided by the debugger.
  1532. //
  1533. case DbgCommandSetRegisters:
  1534. KdpSetRegisters(TrapFrame, Packet->Payload);
  1535. break;
  1536. //
  1537. // The module list header request causes the debugger to send information
  1538. // about all the loaded modules in the system so the debugger can determine
  1539. // if it's in sync.
  1540. //
  1541. case DbgModuleListHeaderRequest:
  1542. KdpSendModuleList(TRUE);
  1543. break;
  1544. //
  1545. // The module list entries request causes the debugger to send a complete
  1546. // list of all loaded modules. This is a much slower operation than just
  1547. // sending the header.
  1548. //
  1549. case DbgModuleListEntriesRequest:
  1550. KdpSendModuleList(FALSE);
  1551. break;
  1552. //
  1553. // The read or write virtual memory request sends or edits host memory.
  1554. //
  1555. case DbgMemoryReadVirtual:
  1556. case DbgMemoryWriteVirtual:
  1557. KdpHandleMemoryAccess();
  1558. break;
  1559. //
  1560. // The switch processor command switches the view to another processor.
  1561. //
  1562. case DbgCommandSwitchProcessor:
  1563. SwitchProcessorRequest = (PSWITCH_PROCESSOR_REQUEST)KdRxPacket.Payload;
  1564. KdFreezeOwner = SwitchProcessorRequest->ProcessorNumber;
  1565. *ContinueExecution = TRUE;
  1566. break;
  1567. //
  1568. // Handle commands for getting and setting special registers.
  1569. //
  1570. case DbgCommandGetSpecialRegisters:
  1571. KdpGetSpecialRegisters((PSPECIAL_REGISTERS_UNION)(KdTxPacket.Payload));
  1572. KdTxPacket.Header.Command = DbgCommandReturnSpecialRegisters;
  1573. KdTxPacket.Header.PayloadSize = sizeof(SPECIAL_REGISTERS_UNION);
  1574. Status = KdpSendPacket(&KdTxPacket, NULL);
  1575. break;
  1576. case DbgCommandSetSpecialRegisters:
  1577. SetSpecialRegisters = (PSET_SPECIAL_REGISTERS)(KdRxPacket.Payload);
  1578. KdpSetSpecialRegisters(&(SetSpecialRegisters->Original),
  1579. &(SetSpecialRegisters->New));
  1580. break;
  1581. //
  1582. // Reboot the system.
  1583. //
  1584. case DbgCommandReboot:
  1585. RebootRequest = (PDEBUG_REBOOT_REQUEST)(KdRxPacket.Payload);
  1586. KdpReboot(RebootRequest->ResetType, Exception, TrapFrame);
  1587. break;
  1588. //
  1589. // If a connection request is found, then the host is out of sync with the
  1590. // target. Resend the connection parameters and break notification.
  1591. //
  1592. case DbgConnectionRequest:
  1593. KdpSendConnectionResponse((PCONNECTION_REQUEST)(KdRxPacket.Payload),
  1594. &BreakInRequested);
  1595. if (Exception == EXCEPTION_POLL_DEBUGGER) {
  1596. //
  1597. // If it's just polling and the caller didn't want a break, then
  1598. // continue. Otherwise, turn the poll into a break.
  1599. //
  1600. if (BreakInRequested == FALSE) {
  1601. *ContinueExecution = TRUE;
  1602. KdFreezeOwner = MAX_ULONG;
  1603. }
  1604. } else {
  1605. //
  1606. // If a break is requested, send the notification.
  1607. //
  1608. if (BreakInRequested != FALSE) {
  1609. KdpInitializeBreakNotification(Exception,
  1610. TrapFrame,
  1611. &KdTxPacket);
  1612. Status = KdpSendPacket(&KdTxPacket, NULL);
  1613. }
  1614. }
  1615. break;
  1616. //
  1617. // Ignore spurious acknowledge commands.
  1618. //
  1619. case DbgPacketAcknowledge:
  1620. break;
  1621. //
  1622. // The command is not recognized. Send the invalid command response.
  1623. //
  1624. default:
  1625. KdTxPacket.Header.Command = DbgConnectionInvalidRequest;
  1626. KdTxPacket.Header.PayloadSize = sizeof(DEBUG_PACKET_HEADER);
  1627. RtlCopyMemory(&KdTxPacket.Payload,
  1628. &KdRxPacket.Header,
  1629. sizeof(DEBUG_PACKET_HEADER));
  1630. Status = KdpSendPacket(&KdTxPacket, NULL);
  1631. break;
  1632. }
  1633. return Status;
  1634. }
  1635. KSTATUS
  1636. KdpPrint (
  1637. PPRINT_PARAMETERS PrintParameters,
  1638. PBOOL BreakInRequested
  1639. )
  1640. /*++
  1641. Routine Description:
  1642. This routine prints a string to the debugger. Currently the maximum length
  1643. string is a little less than one debug packet. This routine MUST be called
  1644. from within the debugger path (not outside kernel code), as it writes to
  1645. the global transmit/receive packets.
  1646. Arguments:
  1647. PrintParameters - Supplies a pointer to the required print parameters.
  1648. BreakInRequested - Supplies an optional pointer where a boolean will be
  1649. returned indicating if the debugger would like to break in.
  1650. Return Value:
  1651. Status code.
  1652. --*/
  1653. {
  1654. ULONG MaxStringLength;
  1655. ULONG StringLength;
  1656. KdTxPacket.Header.Command = DbgPrintString;
  1657. //
  1658. // Print the format string, with the packet as the destination buffer.
  1659. //
  1660. MaxStringLength = DEBUG_PACKET_SIZE - sizeof(DEBUG_PACKET_HEADER);
  1661. StringLength = RtlFormatString((PSTR)(&(KdTxPacket.Payload)),
  1662. MaxStringLength,
  1663. CharacterEncodingDefault,
  1664. PrintParameters->FormatString,
  1665. PrintParameters->Arguments);
  1666. //
  1667. // Print strings cannot be bigger than the packet size. If they are,
  1668. // print out a warning. Otherwise, print the string.
  1669. //
  1670. if (StringLength > MaxStringLength) {
  1671. StringLength = MaxStringLength;
  1672. }
  1673. KdTxPacket.Header.PayloadSize = StringLength;
  1674. return KdpSendPacket(&KdTxPacket, BreakInRequested);
  1675. }
  1676. KSTATUS
  1677. KdpSendProfilingData (
  1678. PBOOL BreakInRequested
  1679. )
  1680. /*++
  1681. Routine Description:
  1682. This routine calls the system profiler for data and sends it to the
  1683. debugger.
  1684. Arguments:
  1685. BreakInRequested - Supplies a pointer where a boolean will be returned
  1686. indicating if the debugger would like to break in.
  1687. Return Value:
  1688. Status code.
  1689. --*/
  1690. {
  1691. ULONG DataSize;
  1692. ULONG Flags;
  1693. BOOL LocalBreakInRequested;
  1694. PPROCESSOR_BLOCK ProcessorBlock;
  1695. PPROFILER_NOTIFICATION ProfilerNotification;
  1696. KSTATUS Status;
  1697. *BreakInRequested = FALSE;
  1698. //
  1699. // Check to see if there is any data to send. Another core may have
  1700. // collected and sent the data since the flags were checked before the
  1701. // debug exception.
  1702. //
  1703. Flags = SpGetProfilerDataStatus();
  1704. if (Flags == 0) {
  1705. Status = STATUS_SUCCESS;
  1706. goto SendProfilingDataEnd;
  1707. }
  1708. ProcessorBlock = KeGetCurrentProcessorBlockForDebugger();
  1709. DataSize = DEBUG_PAYLOAD_SIZE - sizeof(PROFILER_NOTIFICATION_HEADER);
  1710. ProfilerNotification = (PPROFILER_NOTIFICATION)KdTxPacket.Payload;
  1711. KdTxPacket.Header.Command = DbgProfilerNotification;
  1712. //
  1713. // Loop as long as there is more profiling data to send.
  1714. //
  1715. while (Flags != 0) {
  1716. //
  1717. // Initialize the debugger packet for a profiler notification message.
  1718. //
  1719. ASSERT(KdTxPacket.Header.Command == DbgProfilerNotification);
  1720. KdTxPacket.Header.PayloadSize = DEBUG_PAYLOAD_SIZE;
  1721. //
  1722. // Collect the pending profiler data. Exit if something went wrong.
  1723. //
  1724. ProfilerNotification->Header.DataSize = DataSize;
  1725. Status = SpGetProfilerData(ProfilerNotification, &Flags);
  1726. if (!KSUCCESS(Status)) {
  1727. goto SendProfilingDataEnd;
  1728. }
  1729. //
  1730. // Don't bother sending an empty packet. Skip to the next one.
  1731. //
  1732. if (ProfilerNotification->Header.DataSize == 0) {
  1733. continue;
  1734. }
  1735. //
  1736. // Send the profiler notification packet.
  1737. //
  1738. Status = KdpSendPacket(&KdTxPacket, &LocalBreakInRequested);
  1739. if (!KSUCCESS(Status)) {
  1740. goto SendProfilingDataEnd;
  1741. }
  1742. if (LocalBreakInRequested != FALSE) {
  1743. *BreakInRequested = TRUE;
  1744. }
  1745. }
  1746. //
  1747. // Send a final packet to the debugger notifying that this round of sending
  1748. // profiling data is complete.
  1749. //
  1750. ASSERT(KdTxPacket.Header.Command == DbgProfilerNotification);
  1751. KdTxPacket.Header.PayloadSize = sizeof(PROFILER_NOTIFICATION_HEADER);
  1752. ProfilerNotification->Header.DataSize = 0;
  1753. ProfilerNotification->Header.Type = ProfilerDataTypeMax;
  1754. ProfilerNotification->Header.Processor = 0;
  1755. if (ProcessorBlock != NULL) {
  1756. ProfilerNotification->Header.Processor =
  1757. ProcessorBlock->ProcessorNumber;
  1758. }
  1759. Status = KdpSendPacket(&KdTxPacket, &LocalBreakInRequested);
  1760. if (!KSUCCESS(Status)) {
  1761. goto SendProfilingDataEnd;
  1762. }
  1763. if (LocalBreakInRequested != FALSE) {
  1764. *BreakInRequested = TRUE;
  1765. }
  1766. SendProfilingDataEnd:
  1767. return Status;
  1768. }
  1769. ULONG
  1770. KdpValidateMemoryAccess (
  1771. PVOID Address,
  1772. ULONG Length,
  1773. PBOOL Writable
  1774. )
  1775. /*++
  1776. Routine Description:
  1777. This routine validates that access to a specified location in memory will
  1778. not cause a page fault.
  1779. Arguments:
  1780. Address - Supplies the virtual address of the memory that will be read or
  1781. written.
  1782. Length - Supplies how many bytes at that location the caller would like to
  1783. read or write.
  1784. Writable - Supplies an optional pointer that receives a boolean indicating
  1785. whether or not the memory range is mapped writable.
  1786. Return Value:
  1787. Returns the number of bytes from the beginning of the address that are
  1788. accessible. If the memory is completely available, the return value will be
  1789. equal to the Length parameter. If the memory is completely paged out, 0
  1790. will be returned.
  1791. --*/
  1792. {
  1793. if (KdSkipMemoryValidation != FALSE) {
  1794. if (Writable != NULL) {
  1795. *Writable = TRUE;
  1796. }
  1797. return Length;
  1798. }
  1799. return MmValidateMemoryAccessForDebugger(Address, Length, Writable);
  1800. }
  1801. VOID
  1802. KdpModifyAddressMapping (
  1803. PVOID Address,
  1804. BOOL Writable,
  1805. PBOOL WasWritable
  1806. )
  1807. /*++
  1808. Routine Description:
  1809. This routine modifies the mapping properties for the page that contains the
  1810. given address.
  1811. Arguments:
  1812. Address - Supplies the virtual address of the memory whose mapping
  1813. properties are to be changed.
  1814. Writable - Supplies a boolean indicating whether or not to make the page
  1815. containing the address writable (TRUE) or read-only (FALSE).
  1816. WasWritable - Supplies a pointer that receives a boolean indicating whether
  1817. or not the page was writable (TRUE) or read-only (FALSE) before any
  1818. modifications.
  1819. Return Value:
  1820. None.
  1821. --*/
  1822. {
  1823. if (KdSkipMemoryValidation != FALSE) {
  1824. *WasWritable = TRUE;
  1825. return;
  1826. }
  1827. return MmModifyAddressMappingForDebugger(Address, Writable, WasWritable);
  1828. }
  1829. USHORT
  1830. KdpCalculateChecksum (
  1831. PVOID Data,
  1832. ULONG DataLength
  1833. )
  1834. /*++
  1835. Routine Description:
  1836. This routine computes a checksum over a given length. It can handle both odd
  1837. and even length data.
  1838. Arguments:
  1839. Data - Supplies a pointer to the data that is to be checksummed.
  1840. DataLength - Supplies the length of the data buffer, in bytes.
  1841. Return Value:
  1842. Returns the checksum.
  1843. --*/
  1844. {
  1845. USHORT Checksum;
  1846. PUSHORT CurrentData;
  1847. ULONG Index;
  1848. ULONG ShortLength;
  1849. Checksum = 0;
  1850. Index = 0;
  1851. //
  1852. // Checksums are calculated by adding up a series of two-byte values.
  1853. // Convert the pointer to a short pointer and divide bytes by 2 to get size
  1854. // in shorts.
  1855. //
  1856. ShortLength = DataLength / 2;
  1857. CurrentData = (PUSHORT)Data;
  1858. while (Index < ShortLength) {
  1859. Checksum += *CurrentData;
  1860. CurrentData += 1;
  1861. Index += 1;
  1862. }
  1863. //
  1864. // If the data was an odd length, then there's one byte left to be added.
  1865. // Add only that byte.
  1866. //
  1867. if ((ShortLength * 2) != DataLength) {
  1868. Checksum += *((PUCHAR)CurrentData);
  1869. }
  1870. return Checksum;
  1871. }
  1872. KSTATUS
  1873. KdpSendModuleList (
  1874. BOOL SendHeaderOnly
  1875. )
  1876. /*++
  1877. Routine Description:
  1878. This routine sends information to the debugger client about the binaries
  1879. currently loaded in the system.
  1880. Arguments:
  1881. SendHeaderOnly - Supplies a flag indicating that the debugger requested only
  1882. the module list header.
  1883. Return Value:
  1884. Status code.
  1885. --*/
  1886. {
  1887. PDEBUG_MODULE CurrentModule;
  1888. PLIST_ENTRY CurrentModuleListEntry;
  1889. ULONG MaxNameLength;
  1890. PLOADED_MODULE_ENTRY ModuleEntry;
  1891. PMODULE_LIST_HEADER ModuleListHeader;
  1892. PCHAR NameDestination;
  1893. ULONG NameLength;
  1894. PCHAR NameSource;
  1895. ULONG PacketMaxNameLength;
  1896. KSTATUS Status;
  1897. PacketMaxNameLength = sizeof(KdTxPacket.Payload) -
  1898. sizeof(LOADED_MODULE_ENTRY) +
  1899. (sizeof(CHAR) * ANYSIZE_ARRAY);
  1900. //
  1901. // If the loaded modules list has not been initialized, send an error, and
  1902. // return as successful.
  1903. //
  1904. if (KdLoadedModulesInitialized == FALSE) {
  1905. KdTxPacket.Header.Command = DbgModuleListError;
  1906. KdTxPacket.Header.PayloadSize = 0;
  1907. Status = KdpSendPacket(&KdTxPacket, NULL);
  1908. goto SendModuleListEnd;
  1909. }
  1910. //
  1911. // Send the module list header.
  1912. //
  1913. KdTxPacket.Header.Command = DbgModuleListHeader;
  1914. KdTxPacket.Header.PayloadSize = sizeof(MODULE_LIST_HEADER);
  1915. ModuleListHeader = (PMODULE_LIST_HEADER)KdTxPacket.Payload;
  1916. ModuleListHeader->ModuleCount = KdLoadedModules.ModuleCount;
  1917. ModuleListHeader->Signature = KdLoadedModules.Signature;
  1918. Status = KdpSendPacket(&KdTxPacket, NULL);
  1919. if ((!KSUCCESS(Status)) || (SendHeaderOnly != FALSE)) {
  1920. goto SendModuleListEnd;
  1921. }
  1922. //
  1923. // Send all modules.
  1924. //
  1925. KdTxPacket.Header.Command = DbgModuleListEntry;
  1926. ModuleEntry = (PLOADED_MODULE_ENTRY)KdTxPacket.Payload;
  1927. CurrentModuleListEntry = KdLoadedModules.ModulesHead.Next;
  1928. while (CurrentModuleListEntry != &(KdLoadedModules.ModulesHead)) {
  1929. CurrentModule = LIST_VALUE(CurrentModuleListEntry,
  1930. DEBUG_MODULE,
  1931. ListEntry);
  1932. //
  1933. // Copy the name.
  1934. //
  1935. NameSource = CurrentModule->BinaryName;
  1936. NameDestination = ModuleEntry->BinaryName;
  1937. MaxNameLength = CurrentModule->StructureSize - sizeof(DEBUG_MODULE) +
  1938. (ANYSIZE_ARRAY * sizeof(CHAR));
  1939. if (MaxNameLength > PacketMaxNameLength) {
  1940. MaxNameLength = PacketMaxNameLength;
  1941. }
  1942. NameLength = RtlStringCopy(NameDestination, NameSource, MaxNameLength);
  1943. //
  1944. // Copy the rest of the module information, and send the packet.
  1945. //
  1946. ModuleEntry->StructureSize = sizeof(LOADED_MODULE_ENTRY) +
  1947. ((NameLength - ANYSIZE_ARRAY) *
  1948. sizeof(CHAR));
  1949. ModuleEntry->Timestamp = CurrentModule->Timestamp;
  1950. ModuleEntry->BaseAddress = (UINTN)CurrentModule->BaseAddress;
  1951. if (ModuleEntry->BaseAddress == (UINTN)-1ULL) {
  1952. ModuleEntry->BaseAddress = -1ULL;
  1953. }
  1954. ModuleEntry->LowestAddress = (UINTN)CurrentModule->LowestAddress;
  1955. ModuleEntry->Size = CurrentModule->Size;
  1956. ModuleEntry->Process = CurrentModule->Process;
  1957. KdTxPacket.Header.PayloadSize = ModuleEntry->StructureSize;
  1958. Status = KdpSendPacket(&KdTxPacket, NULL);
  1959. if (!KSUCCESS(Status)) {
  1960. goto SendModuleListEnd;
  1961. }
  1962. //
  1963. // Get the next module.
  1964. //
  1965. CurrentModuleListEntry = CurrentModuleListEntry->Next;
  1966. }
  1967. SendModuleListEnd:
  1968. return Status;
  1969. }
  1970. KSTATUS
  1971. KdpHandleMemoryAccess (
  1972. VOID
  1973. )
  1974. /*++
  1975. Routine Description:
  1976. This routine handles memory read and write commands from the debugger.
  1977. Arguments:
  1978. None.
  1979. Return Value:
  1980. Status code.
  1981. --*/
  1982. {
  1983. PBYTE AddressByte;
  1984. PUINTN AddressNatural;
  1985. PVOID Buffer;
  1986. ULONG ByteCount;
  1987. ULONG MaxSize;
  1988. PVOID PageAddress;
  1989. ULONG PageSize;
  1990. BOOL PageWritable;
  1991. PBYTE ReadDestinationByte;
  1992. PUINTN ReadDestinationNatural;
  1993. BOOL RegionWritable;
  1994. PMEMORY_REQUEST Request;
  1995. PMEMORY_CONTENTS Response;
  1996. KSTATUS Status;
  1997. ULONG ValidSize;
  1998. PWRITE_REQUEST_ACKNOWLEDGEMENT WriteAcknowledgement;
  1999. PBYTE WriteSourceByte;
  2000. PUINTN WriteSourceNatural;
  2001. Request = (PMEMORY_REQUEST)KdRxPacket.Payload;
  2002. //
  2003. // Determine that maximum size that could legally be requested and still fit
  2004. // inside a debug packet.
  2005. //
  2006. if (KdRxPacket.Header.Command == DbgMemoryReadVirtual) {
  2007. MaxSize = DEBUG_PACKET_SIZE - sizeof(DEBUG_PACKET_HEADER) -
  2008. sizeof(MEMORY_CONTENTS);
  2009. } else if (KdRxPacket.Header.Command == DbgMemoryWriteVirtual) {
  2010. MaxSize = DEBUG_PACKET_SIZE - sizeof(DEBUG_PACKET_HEADER) -
  2011. sizeof(MEMORY_REQUEST);
  2012. } else {
  2013. MaxSize = 0;
  2014. }
  2015. //
  2016. // If the request is invalid, send back an invalid command packet.
  2017. //
  2018. if (Request->Size > MaxSize) {
  2019. KdTxPacket.Header.Command = DbgInvalidCommand;
  2020. KdTxPacket.Header.PayloadSize = 0;
  2021. }
  2022. //
  2023. // Validate the memory access to make sure the debugger does not cause an
  2024. // access violation.
  2025. //
  2026. AddressByte = (PVOID)(ULONG)Request->Address;
  2027. AddressNatural = (PUINTN)AddressByte;
  2028. ValidSize = KdpValidateMemoryAccess(AddressByte,
  2029. Request->Size,
  2030. &RegionWritable);
  2031. //
  2032. // For reads, copy the contents from memory into the packet.
  2033. //
  2034. if (KdRxPacket.Header.Command == DbgMemoryReadVirtual) {
  2035. KdTxPacket.Header.Command = DbgMemoryContents;
  2036. KdTxPacket.Header.PayloadSize = sizeof(MEMORY_CONTENTS) + ValidSize;
  2037. Response = (PMEMORY_CONTENTS)KdTxPacket.Payload;
  2038. Response->Address = (ULONGLONG)(ULONG)AddressByte;
  2039. Response->Size = ValidSize;
  2040. Buffer = (PVOID)KdTxPacket.Payload + sizeof(MEMORY_CONTENTS);
  2041. //
  2042. // Copy in natural word size chunks if possible.
  2043. //
  2044. if ((ValidSize & (sizeof(UINTN) - 1)) == 0) {
  2045. ReadDestinationNatural = Buffer;
  2046. for (ByteCount = 0;
  2047. ByteCount < ValidSize;
  2048. ByteCount += sizeof(UINTN)) {
  2049. *ReadDestinationNatural = *AddressNatural;
  2050. AddressNatural += 1;
  2051. ReadDestinationNatural += 1;
  2052. }
  2053. //
  2054. // Copy byte for byte.
  2055. //
  2056. } else {
  2057. ReadDestinationByte = Buffer;
  2058. for (ByteCount = 0; ByteCount < ValidSize; ByteCount += 1) {
  2059. *ReadDestinationByte = *AddressByte;
  2060. AddressByte += 1;
  2061. ReadDestinationByte += 1;
  2062. }
  2063. }
  2064. //
  2065. // For writes, copy the contents of the packet into memory.
  2066. //
  2067. } else if (KdRxPacket.Header.Command == DbgMemoryWriteVirtual) {
  2068. KdTxPacket.Header.Command = DbgMemoryWriteAcknowledgement;
  2069. KdTxPacket.Header.PayloadSize = sizeof(WRITE_REQUEST_ACKNOWLEDGEMENT);
  2070. WriteAcknowledgement =
  2071. (PWRITE_REQUEST_ACKNOWLEDGEMENT)KdTxPacket.Payload;
  2072. WriteAcknowledgement->Address = (ULONGLONG)(ULONG)AddressByte;
  2073. WriteAcknowledgement->BytesWritten = ValidSize;
  2074. WriteSourceByte = (PBYTE)KdRxPacket.Payload + sizeof(MEMORY_REQUEST);
  2075. WriteSourceNatural = (PUINTN)WriteSourceByte;
  2076. //
  2077. // Copy in natural word size chunks if possible.
  2078. //
  2079. PageAddress = NULL;
  2080. PageSize = MmPageSize();
  2081. PageWritable = FALSE;
  2082. if ((ValidSize & (sizeof(UINTN) - 1)) == 0) {
  2083. for (ByteCount = 0;
  2084. ByteCount < ValidSize;
  2085. ByteCount += sizeof(UINTN)) {
  2086. //
  2087. // Make sure the current page is mapped writable if the entire
  2088. // region was determined to not be writable.
  2089. //
  2090. if ((RegionWritable == FALSE) && (PageAddress == NULL)) {
  2091. PageAddress = ALIGN_POINTER_DOWN(AddressNatural, PageSize);
  2092. KdpModifyAddressMapping(PageAddress, TRUE, &PageWritable);
  2093. }
  2094. *AddressNatural = *WriteSourceNatural;
  2095. KdpCleanMemory(AddressNatural);
  2096. WriteSourceNatural += 1;
  2097. AddressNatural += 1;
  2098. //
  2099. // If the entire region was not writable and a new page is up
  2100. // next, then set the last page back to read-only if it was not
  2101. // originally writable.
  2102. //
  2103. if ((RegionWritable == FALSE) &&
  2104. (PageAddress !=
  2105. ALIGN_POINTER_DOWN(AddressNatural, PageSize))) {
  2106. ASSERT(PageAddress != NULL);
  2107. if (PageWritable == FALSE) {
  2108. KdpModifyAddressMapping(PageAddress,
  2109. FALSE,
  2110. &PageWritable);
  2111. }
  2112. PageAddress = NULL;
  2113. }
  2114. }
  2115. //
  2116. // Copy byte for byte.
  2117. //
  2118. } else {
  2119. for (ByteCount = 0; ByteCount < ValidSize; ByteCount += 1) {
  2120. //
  2121. // Make sure the current page is mapped writable if the entire
  2122. // region was determined to not be writable.
  2123. //
  2124. if ((RegionWritable == FALSE) && (PageAddress == NULL)) {
  2125. PageAddress = ALIGN_POINTER_DOWN(AddressByte, PageSize);
  2126. KdpModifyAddressMapping(PageAddress, TRUE, &PageWritable);
  2127. }
  2128. *AddressByte = *WriteSourceByte;
  2129. KdpCleanMemory(AddressByte);
  2130. AddressByte += 1;
  2131. WriteSourceByte += 1;
  2132. //
  2133. // If the entire region was not writable and a new page is up
  2134. // next, then set the last page back to read-only if it was not
  2135. // originally writable.
  2136. //
  2137. if ((RegionWritable == FALSE) &&
  2138. (PageAddress !=
  2139. ALIGN_POINTER_DOWN(AddressByte, PageSize))) {
  2140. ASSERT(PageAddress != NULL);
  2141. if (PageWritable == FALSE) {
  2142. KdpModifyAddressMapping(PageAddress,
  2143. FALSE,
  2144. &PageWritable);
  2145. }
  2146. PageAddress = NULL;
  2147. }
  2148. }
  2149. }
  2150. //
  2151. // If the entire region was not writable, then the last page might have
  2152. // been left in the incorrect state. If the page address is valid and
  2153. // it was not writable, then modify it to read-only.
  2154. //
  2155. if ((RegionWritable == FALSE) &&
  2156. (PageWritable == FALSE) &&
  2157. (PageAddress != NULL)) {
  2158. KdpModifyAddressMapping(PageAddress, FALSE, &PageWritable);
  2159. }
  2160. //
  2161. // For unknown requests, the response will be an invalid request packet.
  2162. //
  2163. } else {
  2164. KdTxPacket.Header.Command = DbgInvalidCommand;
  2165. KdTxPacket.Header.PayloadSize = 0;
  2166. }
  2167. //
  2168. // Send the response.
  2169. //
  2170. Status = KdpSendPacket(&KdTxPacket, NULL);
  2171. return Status;
  2172. }
  2173. VOID
  2174. KdpInitializeBreakNotification (
  2175. ULONG Exception,
  2176. PTRAP_FRAME TrapFrame,
  2177. PDEBUG_PACKET Packet
  2178. )
  2179. /*++
  2180. Routine Description:
  2181. This routine initializes a break notification structure to be sent to the
  2182. debugger.
  2183. Arguments:
  2184. Exception - Supplies the type of exception to notify the debugger about.
  2185. TrapFrame - Supplies a pointer to the current trap frame.
  2186. Packet - Supplies a pointer to receive the debug packet to send to the
  2187. debugger.
  2188. Return Value:
  2189. None.
  2190. --*/
  2191. {
  2192. PBREAK_NOTIFICATION BreakNotification;
  2193. PVOID InstructionPointer;
  2194. PVOID InstructionPointerAddress;
  2195. PBYTE InstructionStream;
  2196. ULONG InstructionStreamBytes;
  2197. PKPROCESS Process;
  2198. PPROCESSOR_BLOCK ProcessorBlock;
  2199. ULONG StreamIndex;
  2200. //
  2201. // Begin to initialize the break notification that will be sent to the
  2202. // debugger.
  2203. //
  2204. BreakNotification = (PBREAK_NOTIFICATION)Packet->Payload;
  2205. BreakNotification->LoadedModuleCount = KdLoadedModules.ModuleCount;
  2206. BreakNotification->LoadedModuleSignature = KdLoadedModules.Signature;
  2207. //
  2208. // Initialize the processor number, but be careful about reaching through
  2209. // the processor block as it will be NULL in the loader or very early
  2210. // kernel init.
  2211. //
  2212. BreakNotification->ProcessorOrThreadCount = 1;
  2213. BreakNotification->ProcessorOrThreadNumber = 0;
  2214. BreakNotification->Process = 0;
  2215. BreakNotification->ProcessorBlock = (UINTN)NULL;
  2216. if (KeActiveProcessorCount != 0) {
  2217. ProcessorBlock = KeGetCurrentProcessorBlockForDebugger();
  2218. if (ProcessorBlock != NULL) {
  2219. BreakNotification->ProcessorOrThreadCount = KeActiveProcessorCount;
  2220. BreakNotification->ProcessorOrThreadNumber =
  2221. ProcessorBlock->ProcessorNumber;
  2222. BreakNotification->ProcessorBlock = (UINTN)ProcessorBlock;
  2223. //
  2224. // Reach out to get the current process ID. It would be safer (but
  2225. // also slower) if each of these pointer reach-throughs was
  2226. // validated first. Doing the validation would really only save
  2227. // cases where the current thread or process structure was severely
  2228. // corrupted.
  2229. //
  2230. if ((ProcessorBlock->RunningThread != NULL) &&
  2231. (ProcessorBlock->RunningThread->OwningProcess != NULL)) {
  2232. Process = ProcessorBlock->RunningThread->OwningProcess;
  2233. BreakNotification->Process = Process->Identifiers.ProcessId;
  2234. }
  2235. }
  2236. }
  2237. InstructionPointer = KdpGetInstructionPointer(TrapFrame);
  2238. InstructionPointerAddress = KdpGetInstructionPointerAddress(TrapFrame);
  2239. BreakNotification->InstructionPointer = (UINTN)InstructionPointer;
  2240. BreakNotification->ErrorCode = 0;
  2241. //
  2242. // If this was a break exception, set the exception type based on whether or
  2243. // not this was an official breakpoint or some random int3.
  2244. //
  2245. if (Exception == EXCEPTION_BREAK) {
  2246. BreakNotification->Exception = ExceptionDebugBreak;
  2247. } else if (Exception == EXCEPTION_SINGLE_STEP) {
  2248. BreakNotification->Exception = ExceptionSingleStep;
  2249. } else if (Exception == EXCEPTION_ASSERTION_FAILURE) {
  2250. BreakNotification->Exception = ExceptionAssertionFailure;
  2251. } else if (Exception == EXCEPTION_ACCESS_VIOLATION) {
  2252. BreakNotification->Exception = ExceptionAccessViolation;
  2253. BreakNotification->ErrorCode = KdpGetErrorCode(Exception, TrapFrame);
  2254. } else if (Exception == EXCEPTION_DOUBLE_FAULT) {
  2255. BreakNotification->Exception = ExceptionDoubleFault;
  2256. BreakNotification->ErrorCode = 0;
  2257. } else if (Exception == EXCEPTION_UNDEFINED_INSTRUCTION) {
  2258. BreakNotification->Exception = ExceptionIllegalInstruction;
  2259. } else if (Exception == EXCEPTION_DEBUGGER_CONNECT) {
  2260. BreakNotification->Exception = ExceptionDebugBreak;
  2261. //
  2262. // This was an unknown exception.
  2263. //
  2264. } else {
  2265. BreakNotification->Exception = ExceptionUnknown;
  2266. }
  2267. //
  2268. // Read in the instruction stream, validating access. As a safety, don't
  2269. // read from instruction pointers that are NULL.
  2270. //
  2271. InstructionStreamBytes = KdpValidateMemoryAccess(
  2272. InstructionPointerAddress,
  2273. BREAK_NOTIFICATION_STREAM_SIZE,
  2274. NULL);
  2275. RtlZeroMemory(BreakNotification->InstructionStream,
  2276. BREAK_NOTIFICATION_STREAM_SIZE);
  2277. if ((TrapFrame != NULL) && (InstructionPointer != NULL)) {
  2278. InstructionStream = InstructionPointerAddress;
  2279. for (StreamIndex = 0;
  2280. StreamIndex < InstructionStreamBytes;
  2281. StreamIndex += 1) {
  2282. BreakNotification->InstructionStream[StreamIndex] =
  2283. *InstructionStream;
  2284. InstructionStream += 1;
  2285. }
  2286. }
  2287. //
  2288. // Copy in the trap frame registers.
  2289. //
  2290. KdpGetRegisters(TrapFrame, &(BreakNotification->Registers));
  2291. //
  2292. // Send the break notification to the debugger.
  2293. //
  2294. Packet->Header.Command = DbgBreakNotification;
  2295. Packet->Header.PayloadSize = sizeof(BREAK_NOTIFICATION);
  2296. return;
  2297. }
  2298. VOID
  2299. KdpReboot (
  2300. DEBUG_REBOOT_TYPE RebootType,
  2301. ULONG Exception,
  2302. PTRAP_FRAME TrapFrame
  2303. )
  2304. /*++
  2305. Routine Description:
  2306. This routine attempts to reboot the target machine.
  2307. Arguments:
  2308. RebootType - Supplies the reboot type.
  2309. Exception - Supplies the original exception code.
  2310. TrapFrame - Supplies a pointer to the trap frame, used to reinitialize the
  2311. debugger connection after a failed reboot attempt.
  2312. Return Value:
  2313. None.
  2314. --*/
  2315. {
  2316. SYSTEM_RESET_TYPE ResetType;
  2317. KSTATUS Status;
  2318. ResetType = SystemResetWarm;
  2319. switch (RebootType) {
  2320. case DebugRebootShutdown:
  2321. ResetType = SystemResetShutdown;
  2322. break;
  2323. case DebugRebootWarm:
  2324. ResetType = SystemResetWarm;
  2325. break;
  2326. case DebugRebootCold:
  2327. ResetType = SystemResetCold;
  2328. break;
  2329. default:
  2330. break;
  2331. }
  2332. KdpDisconnect();
  2333. Status = HlResetSystem(ResetType);
  2334. KdpConnect(NULL);
  2335. KdpInternalPrint("Reset system failed with status %x\n", Status);
  2336. KdpInitializeBreakNotification(Exception, TrapFrame, &KdTxPacket);
  2337. KdpSendPacket(&KdTxPacket, NULL);
  2338. return;
  2339. }
  2340. VOID
  2341. KdpDisconnect (
  2342. VOID
  2343. )
  2344. /*++
  2345. Routine Description:
  2346. This routine disconnects the target from the host.
  2347. Arguments:
  2348. None.
  2349. Return Value:
  2350. None.
  2351. --*/
  2352. {
  2353. PSHUTDOWN_NOTIFICATION Notification;
  2354. if (KdDebuggerConnected == FALSE) {
  2355. return;
  2356. }
  2357. Notification = (PSHUTDOWN_NOTIFICATION)KdTxPacket.Payload;
  2358. Notification->UnloadAllSymbols = TRUE;
  2359. Notification->ShutdownType = ShutdownTypeTransition;
  2360. Notification->Process = 0;
  2361. Notification->ExitStatus = 0;
  2362. KdTxPacket.Header.Command = DbgShutdownNotification;
  2363. KdTxPacket.Header.PayloadSize = sizeof(SHUTDOWN_NOTIFICATION);
  2364. KdpSendPacket(&KdTxPacket, NULL);
  2365. KdpDeviceDisconnect();
  2366. KdDebuggerConnected = FALSE;
  2367. return;
  2368. }
  2369. KSTATUS
  2370. KdpConnect (
  2371. PBOOL BreakInRequested
  2372. )
  2373. /*++
  2374. Routine Description:
  2375. This routine attempts to connect to the kernel debugger.
  2376. Arguments:
  2377. BreakInRequested - Supplies a pointer where a boolean will be returned
  2378. indicating if an initial break is requested.
  2379. Return Value:
  2380. Status code. If the status is failing, the debugger connected global will
  2381. be set to FALSE.
  2382. --*/
  2383. {
  2384. PCONNECTION_REQUEST ConnectionRequest;
  2385. KSTATUS Status;
  2386. if (KdDebuggerConnected != FALSE) {
  2387. return STATUS_SUCCESS;
  2388. }
  2389. //
  2390. // Initialize the serial port for use.
  2391. //
  2392. Status = KdpDeviceReset(DEBUG_DEFAULT_BAUD_RATE);
  2393. if (!KSUCCESS(Status)) {
  2394. goto ConnectEnd;
  2395. }
  2396. if (BreakInRequested != NULL) {
  2397. *BreakInRequested = FALSE;
  2398. }
  2399. //
  2400. // Let the host know a new connection is present.
  2401. //
  2402. KdpSynchronize();
  2403. //
  2404. // Attempt to receive the connection request packet.
  2405. //
  2406. while (TRUE) {
  2407. Status = KdpReceivePacket(&KdRxPacket, KdConnectionTimeout);
  2408. //
  2409. // If a synchronize byte was found, reply to it and try again.
  2410. //
  2411. if (Status == STATUS_CONNECTION_RESET) {
  2412. KdpSynchronize();
  2413. continue;
  2414. }
  2415. if (!KSUCCESS(Status)) {
  2416. goto ConnectEnd;
  2417. }
  2418. if (KdRxPacket.Header.Command != DbgConnectionRequest) {
  2419. KdTxPacket.Header.Command = DbgConnectionUninitialized;
  2420. KdTxPacket.Header.PayloadSize = 0;
  2421. KdpSendPacket(&KdTxPacket, NULL);
  2422. } else {
  2423. break;
  2424. }
  2425. }
  2426. ConnectionRequest = (PCONNECTION_REQUEST)(KdRxPacket.Payload);
  2427. Status = KdpSendConnectionResponse(ConnectionRequest, BreakInRequested);
  2428. if (!KSUCCESS(Status)) {
  2429. goto ConnectEnd;
  2430. }
  2431. ConnectEnd:
  2432. return Status;
  2433. }
  2434. VOID
  2435. KdpSynchronize (
  2436. VOID
  2437. )
  2438. /*++
  2439. Routine Description:
  2440. This routine synchronizes with the kernel debugger in preparation for
  2441. receiving the connection request packet. The synchornization process is a
  2442. simply exchange of bytes where both sides must send a SYN, ACK the other
  2443. side's SYN, and receive an ACK.
  2444. Arguments:
  2445. None.
  2446. Return Value:
  2447. None. Failure is considered non-fatal.
  2448. --*/
  2449. {
  2450. UCHAR SynchronizeByte;
  2451. SynchronizeByte = DEBUG_SYNCHRONIZE_TARGET;
  2452. KdpTransmitBytes(&SynchronizeByte, 1);
  2453. return;
  2454. }
  2455. KSTATUS
  2456. KdpSendConnectionResponse (
  2457. PCONNECTION_REQUEST ConnectionRequest,
  2458. PBOOL BreakInRequested
  2459. )
  2460. /*++
  2461. Routine Description:
  2462. This routine attempts to connect to the kernel debugger.
  2463. Arguments:
  2464. ConnectionRequest - Supplies a pointer to the connection request.
  2465. BreakInRequested - Supplies an optional pointer where a boolean will be
  2466. returned indicating if an initial break is requested.
  2467. Return Value:
  2468. Status code. If the status is failing, the debugger connected global will
  2469. be set to FALSE.
  2470. --*/
  2471. {
  2472. BOOL AcknowledgeBreakRequested;
  2473. PCONNECTION_RESPONSE ConnectionResponse;
  2474. KSTATUS OverallStatus;
  2475. KSTATUS Status;
  2476. ULONG StringSize;
  2477. SYSTEM_VERSION_INFORMATION SystemVersion;
  2478. OverallStatus = STATUS_SUCCESS;
  2479. //
  2480. // Compare protocol version numbers.
  2481. //
  2482. if (ConnectionRequest->ProtocolMajorVersion <
  2483. DEBUG_PROTOCOL_MAJOR_VERSION) {
  2484. //
  2485. // Protocols do not match. Send back the kernel's debugger
  2486. // protocol information, and return. Consider the debugger to be
  2487. // disconnected at this point.
  2488. //
  2489. KdTxPacket.Header.Command = DbgConnectionWrongVersion;
  2490. OverallStatus = STATUS_VERSION_MISMATCH;
  2491. } else {
  2492. KdTxPacket.Header.Command = DbgConnectionAcknowledge;
  2493. }
  2494. if (BreakInRequested != NULL) {
  2495. *BreakInRequested = ConnectionRequest->BreakRequested;
  2496. }
  2497. //
  2498. // Fill out and send the connection response.
  2499. //
  2500. ConnectionResponse = (PCONNECTION_RESPONSE)(KdTxPacket.Payload);
  2501. RtlZeroMemory(ConnectionResponse, sizeof(CONNECTION_RESPONSE));
  2502. ConnectionResponse->ProtocolMajorVersion = DEBUG_PROTOCOL_MAJOR_VERSION;
  2503. ConnectionResponse->ProtocolRevision = DEBUG_PROTOCOL_REVISION;
  2504. StringSize = DEBUG_PAYLOAD_SIZE - sizeof(CONNECTION_RESPONSE);
  2505. Status = KeGetSystemVersion(&SystemVersion,
  2506. ConnectionResponse + 1,
  2507. &StringSize);
  2508. if (KSUCCESS(Status)) {
  2509. ConnectionResponse->SystemMajorVersion = SystemVersion.MajorVersion;
  2510. ConnectionResponse->SystemMinorVersion = SystemVersion.MinorVersion;
  2511. ConnectionResponse->SystemRevision = SystemVersion.Revision;
  2512. ConnectionResponse->SystemSerialVersion = SystemVersion.SerialVersion;
  2513. ConnectionResponse->SystemReleaseLevel = SystemVersion.ReleaseLevel;
  2514. ConnectionResponse->SystemBuildDebugLevel = SystemVersion.DebugLevel;
  2515. ConnectionResponse->SystemBuildTime = SystemVersion.BuildTime.Seconds;
  2516. ConnectionResponse->ProductNameOffset =
  2517. (UINTN)(SystemVersion.ProductName) -
  2518. (UINTN)(KdTxPacket.Payload);
  2519. if (SystemVersion.BuildString != NULL) {
  2520. ConnectionResponse->BuildStringOffset =
  2521. (UINTN)(SystemVersion.BuildString) -
  2522. (UINTN)(KdTxPacket.Payload);
  2523. }
  2524. }
  2525. ConnectionResponse->Machine = KdMachineType;
  2526. KdTxPacket.Header.PayloadSize = sizeof(CONNECTION_RESPONSE) + StringSize;
  2527. Status = KdpSendPacket(&KdTxPacket, &AcknowledgeBreakRequested);
  2528. if (!KSUCCESS(Status)) {
  2529. OverallStatus = Status;
  2530. goto SendConnectionResponseEnd;
  2531. }
  2532. if ((BreakInRequested != NULL) && (AcknowledgeBreakRequested != FALSE)) {
  2533. *BreakInRequested = TRUE;
  2534. }
  2535. if (KdTxPacket.Header.Command == DbgConnectionAcknowledge) {
  2536. KdDebuggerConnected = TRUE;
  2537. }
  2538. SendConnectionResponseEnd:
  2539. return OverallStatus;
  2540. }
  2541. VOID
  2542. KdpInternalPrint (
  2543. PSTR Format,
  2544. ...
  2545. )
  2546. /*++
  2547. Routine Description:
  2548. This routine prints to the debug client window. This routine can only be
  2549. called from *inside* the debug exception handler.
  2550. Arguments:
  2551. Format - Supplies the printf-style format string.
  2552. ... - Supplies additional values as dictated by the format.
  2553. Return Value:
  2554. None.
  2555. --*/
  2556. {
  2557. PRINT_PARAMETERS PrintParameters;
  2558. PrintParameters.FormatString = Format;
  2559. va_start(PrintParameters.Arguments, Format);
  2560. KdpPrint(&PrintParameters, NULL);
  2561. va_end(PrintParameters.Arguments);
  2562. return;
  2563. }
  2564. VOID
  2565. KdpAcquireDebuggerLock (
  2566. PTRAP_FRAME TrapFrame
  2567. )
  2568. /*++
  2569. Routine Description:
  2570. This routine acquires the master debugger lock, ensuring that only one
  2571. processor is speaking out the debugger port at a time.
  2572. Arguments:
  2573. TrapFrame - Supplies a pointer to the trap frame, which is used in case
  2574. this processor needs to respond to a freeze request and become a
  2575. subordinate processor.
  2576. Return Value:
  2577. None.
  2578. --*/
  2579. {
  2580. ULONG LockValue;
  2581. PPROCESSOR_BLOCK ProcessorBlock;
  2582. ULONG ProcessorNumber;
  2583. ProcessorNumber = 0;
  2584. ProcessorBlock = KeGetCurrentProcessorBlockForDebugger();
  2585. if (ProcessorBlock != NULL) {
  2586. ProcessorNumber = ProcessorBlock->ProcessorNumber;
  2587. }
  2588. do {
  2589. LockValue = KdpAtomicCompareExchange32(&KdLockAcquired,
  2590. ProcessorNumber,
  2591. -1);
  2592. //
  2593. // If the lock was not acquired and freeze requests are maskable,
  2594. // look to see if another processor got the lock and is trying to
  2595. // send a freeze request. If this is the case, there's a freeze
  2596. // interrupt pending, which this processor will never get in this loop
  2597. // as interrupts are disabled. Manually freeze, then mark that the
  2598. // freeze, when it does come in, is expected.
  2599. //
  2600. if ((LockValue != -1) &&
  2601. (KeActiveProcessorCount > 1) &&
  2602. (KdFreezesAreMaskable != FALSE) &&
  2603. (KdFreezeOwner != MAX_ULONG) &&
  2604. (KdNmiBroadcastAllowed != FALSE)) {
  2605. KdNmiHandler(TrapFrame);
  2606. }
  2607. } while (LockValue != ProcessorNumber);
  2608. return;
  2609. }
  2610. VOID
  2611. KdpReleaseDebuggerLock (
  2612. VOID
  2613. )
  2614. /*++
  2615. Routine Description:
  2616. This routine releases the master debugging lock.
  2617. Arguments:
  2618. None.
  2619. Return Value:
  2620. None.
  2621. --*/
  2622. {
  2623. ULONG LockValue;
  2624. PPROCESSOR_BLOCK ProcessorBlock;
  2625. ULONG ProcessorNumber;
  2626. ProcessorNumber = 0;
  2627. ProcessorBlock = KeGetCurrentProcessorBlockForDebugger();
  2628. if (ProcessorBlock != NULL) {
  2629. ProcessorNumber = ProcessorBlock->ProcessorNumber;
  2630. }
  2631. LockValue = KdpAtomicCompareExchange32(&KdLockAcquired,
  2632. -1,
  2633. ProcessorNumber);
  2634. ASSERT(LockValue == ProcessorNumber);
  2635. return;
  2636. }
  2637. KSTATUS
  2638. KdpTransmitBytes (
  2639. PVOID Data,
  2640. ULONG Size
  2641. )
  2642. /*++
  2643. Routine Description:
  2644. This routine sends bytes down the transmit to the debug host.
  2645. Arguments:
  2646. Data - Supplies the data to transmit.
  2647. Size - Supplies the number of bytes to transmit.
  2648. Return Value:
  2649. STATUS_SUCCESS on success.
  2650. STATUS_TIMEOUT if the desired number of bytes could not be retrieved in a
  2651. timely fashion.
  2652. STATUS_DEVICE_IO_ERROR if a device error occurred.
  2653. --*/
  2654. {
  2655. PUCHAR Bytes;
  2656. UCHAR EncodedByte[2];
  2657. ULONG SendSize;
  2658. KSTATUS Status;
  2659. Bytes = Data;
  2660. Status = STATUS_SUCCESS;
  2661. while (Size != 0) {
  2662. if (KdEncodeBytes != FALSE) {
  2663. //
  2664. // Gather bytes until one is found that needs escaping.
  2665. //
  2666. SendSize = 0;
  2667. while ((SendSize < Size) &&
  2668. (Bytes[SendSize] != DEBUG_XON) &&
  2669. (Bytes[SendSize] != DEBUG_XOFF) &&
  2670. (Bytes[SendSize] != DEBUG_ESCAPE)) {
  2671. SendSize += 1;
  2672. }
  2673. //
  2674. // If not encoding bytes, just send everything.
  2675. //
  2676. } else {
  2677. SendSize = Size;
  2678. }
  2679. //
  2680. // Send off the buffer so far.
  2681. //
  2682. if (SendSize != 0) {
  2683. Status = KdpDeviceTransmit(Bytes, SendSize);
  2684. if (!KSUCCESS(Status)) {
  2685. break;
  2686. }
  2687. }
  2688. Bytes += SendSize;
  2689. Size -= SendSize;
  2690. //
  2691. // Send an encoded byte.
  2692. //
  2693. if (Size != 0) {
  2694. EncodedByte[0] = DEBUG_ESCAPE;
  2695. EncodedByte[1] = *Bytes + DEBUG_ESCAPE;
  2696. Status = KdpDeviceTransmit(EncodedByte, 2);
  2697. if (!KSUCCESS(Status)) {
  2698. break;
  2699. }
  2700. Size -= 1;
  2701. Bytes += 1;
  2702. }
  2703. }
  2704. return Status;
  2705. }
  2706. KSTATUS
  2707. KdpReceiveBuffer (
  2708. PVOID Data,
  2709. PULONG Size,
  2710. PULONG Timeout
  2711. )
  2712. /*++
  2713. Routine Description:
  2714. This routine receives incoming data from the debug device.
  2715. Arguments:
  2716. Data - Supplies a pointer where the read data will be returned on success.
  2717. Size - Supplies a pointer that on input contains the size of the receive
  2718. buffer. On output, returns the number of bytes read.
  2719. Timeout - Supplies a pointer that on input contains the number of
  2720. microseconds to wait before timing out. On output, will contain the
  2721. remainder of that wait.
  2722. Return Value:
  2723. STATUS_SUCCESS on success.
  2724. STATUS_TIMEOUT if the desired number of bytes could not be retrieved in a
  2725. timely fashion.
  2726. STATUS_DEVICE_IO_ERROR if a device error occurred.
  2727. --*/
  2728. {
  2729. PUCHAR Bytes;
  2730. ULONG BytesCompleted;
  2731. ULONG BytesRemaining;
  2732. ULONG Count;
  2733. ULONG Index;
  2734. ULONG MoveIndex;
  2735. BOOL NextEscaped;
  2736. KSTATUS Status;
  2737. NextEscaped = FALSE;
  2738. Status = STATUS_SUCCESS;
  2739. Bytes = Data;
  2740. BytesRemaining = *Size;
  2741. while (BytesRemaining != 0) {
  2742. BytesCompleted = BytesRemaining;
  2743. Status = KdpDeviceReceiveBuffer(Bytes, &BytesCompleted, Timeout);
  2744. if (!KSUCCESS(Status)) {
  2745. break;
  2746. }
  2747. //
  2748. // If escaping is on, then remove any escape bytes found, and fix up
  2749. // the escaped byte.
  2750. //
  2751. Count = 0;
  2752. if (KdEncodeBytes != FALSE) {
  2753. //
  2754. // If the last byte received was an escape, then unescape this
  2755. // first byte.
  2756. //
  2757. if (NextEscaped != FALSE) {
  2758. NextEscaped = FALSE;
  2759. Bytes[0] -= DEBUG_ESCAPE;
  2760. Bytes += 1;
  2761. BytesRemaining -= 1;
  2762. BytesCompleted -= 1;
  2763. if (BytesRemaining == 0) {
  2764. break;
  2765. }
  2766. }
  2767. for (Index = 0; Index < BytesCompleted - 1; Index += 1) {
  2768. if (Bytes[Index] == DEBUG_ESCAPE) {
  2769. for (MoveIndex = Index;
  2770. MoveIndex < BytesCompleted - 1;
  2771. MoveIndex += 1) {
  2772. Bytes[MoveIndex] = Bytes[MoveIndex + 1];
  2773. }
  2774. Count += 1;
  2775. Bytes[Index] -= DEBUG_ESCAPE;
  2776. }
  2777. }
  2778. //
  2779. // If the last byte received is an escape, remember to unescape the
  2780. // next byte.
  2781. //
  2782. if (Bytes[Index] == DEBUG_ESCAPE) {
  2783. Count += 1;
  2784. NextEscaped = TRUE;
  2785. }
  2786. }
  2787. BytesCompleted -= Count;
  2788. Bytes += BytesCompleted;
  2789. //
  2790. // If the count is non-zero, fewer real bytes were received than
  2791. // expected, so go get the extra ones.
  2792. //
  2793. BytesRemaining -= BytesCompleted;
  2794. }
  2795. *Size -= BytesRemaining;
  2796. return Status;
  2797. }
  2798. KSTATUS
  2799. KdpDeviceReceiveBuffer (
  2800. PVOID Data,
  2801. PULONG Size,
  2802. PULONG Timeout
  2803. )
  2804. /*++
  2805. Routine Description:
  2806. This routine receives incoming data from the debug device.
  2807. Arguments:
  2808. Data - Supplies a pointer where the read data will be returned on success.
  2809. Size - Supplies a pointer that on input contains the size of the receive
  2810. buffer. On output, returns the number of bytes read.
  2811. Timeout - Supplies a pointer that on input contains the number of
  2812. microseconds to wait before timing out. On output, will contain the
  2813. remainder of that wait.
  2814. Return Value:
  2815. STATUS_SUCCESS on success.
  2816. STATUS_TIMEOUT if the desired number of bytes could not be retrieved in a
  2817. timely fashion.
  2818. STATUS_DEVICE_IO_ERROR if a device error occurred.
  2819. --*/
  2820. {
  2821. ULONG BytesCompleted;
  2822. ULONG BytesRemaining;
  2823. ULONG StallDuration;
  2824. KSTATUS Status;
  2825. //
  2826. // Loop until all data has been received. The first time around, do a
  2827. // smaller delay. This way if a stream is being sent reliably but not
  2828. // back to back, the larger delay doesn't get stuck in between each byte.
  2829. //
  2830. BytesRemaining = *Size;
  2831. StallDuration = DEBUG_SMALL_STALL;
  2832. Status = STATUS_SUCCESS;
  2833. while (BytesRemaining != 0) {
  2834. BytesCompleted = BytesRemaining;
  2835. Status = KdpDeviceReceive(Data, &BytesCompleted);
  2836. BytesRemaining -= BytesCompleted;
  2837. if (Status == STATUS_NO_DATA_AVAILABLE) {
  2838. //
  2839. // Avoid both the time counter and stalls if the boolean is set.
  2840. //
  2841. if (KdAvoidTimeCounter != FALSE) {
  2842. continue;
  2843. }
  2844. //
  2845. // Keep the time counter fresh.
  2846. //
  2847. HlQueryTimeCounter();
  2848. if (*Timeout == MAX_ULONG) {
  2849. continue;
  2850. } else if (*Timeout == 0) {
  2851. Status = STATUS_TIMEOUT;
  2852. break;
  2853. } else if (*Timeout < StallDuration) {
  2854. *Timeout = StallDuration;
  2855. }
  2856. //
  2857. // Stall to count time towards the timeout.
  2858. //
  2859. HlBusySpin(StallDuration);
  2860. *Timeout -= StallDuration;
  2861. StallDuration = DEBUG_STALL_INCREMENT;
  2862. continue;
  2863. } else if (!KSUCCESS(Status)) {
  2864. break;
  2865. }
  2866. Data += BytesCompleted;
  2867. StallDuration = DEBUG_SMALL_STALL;
  2868. }
  2869. *Size -= BytesRemaining;
  2870. return Status;
  2871. }
  2872. KSTATUS
  2873. KdpDeviceReset (
  2874. ULONG BaudRate
  2875. )
  2876. /*++
  2877. Routine Description:
  2878. This routine initializes and resets a debug device, preparing it to send
  2879. and receive data.
  2880. Arguments:
  2881. BaudRate - Supplies the baud rate to set.
  2882. Return Value:
  2883. STATUS_SUCCESS on success.
  2884. Other status codes on failure. The device will not be used if a failure
  2885. status code is returned.
  2886. --*/
  2887. {
  2888. KSTATUS Status;
  2889. KD_DEVICE_TRACE(KdDeviceTraceResetting);
  2890. if (KdDebugDevice == NULL) {
  2891. Status = STATUS_NO_SUCH_DEVICE;
  2892. goto DeviceResetEnd;
  2893. }
  2894. Status = KdDebugDevice->FunctionTable.Reset(KdDebugDevice->Context,
  2895. BaudRate);
  2896. DeviceResetEnd:
  2897. if (!KSUCCESS(Status)) {
  2898. KD_DEVICE_TRACE(KdDeviceTraceResetFailed);
  2899. } else {
  2900. KD_DEVICE_TRACE(KdDeviceTraceResetComplete);
  2901. }
  2902. return Status;
  2903. }
  2904. KSTATUS
  2905. KdpDeviceTransmit (
  2906. PVOID Data,
  2907. ULONG Size
  2908. )
  2909. /*++
  2910. Routine Description:
  2911. This routine transmits data from the host out through the debug device.
  2912. Arguments:
  2913. Data - Supplies a pointer to the data to write.
  2914. Size - Supplies the size to write, in bytes.
  2915. Return Value:
  2916. STATUS_SUCCESS on success.
  2917. STATUS_DEVICE_IO_ERROR if a device error occurred.
  2918. --*/
  2919. {
  2920. KSTATUS Status;
  2921. KD_DEVICE_TRACE(KdDeviceTraceTransmitting);
  2922. if (KdDebugDevice == NULL) {
  2923. Status = STATUS_NO_SUCH_DEVICE;
  2924. goto DeviceTransmitEnd;
  2925. }
  2926. Status = KdDebugDevice->FunctionTable.Transmit(KdDebugDevice->Context,
  2927. Data,
  2928. Size);
  2929. DeviceTransmitEnd:
  2930. if (!KSUCCESS(Status)) {
  2931. KD_DEVICE_TRACE(KdDeviceTraceTransmitFailed);
  2932. } else {
  2933. KD_DEVICE_TRACE(KdDeviceTraceTransmitComplete);
  2934. }
  2935. return Status;
  2936. }
  2937. KSTATUS
  2938. KdpDeviceReceive (
  2939. PVOID Data,
  2940. PULONG Size
  2941. )
  2942. /*++
  2943. Routine Description:
  2944. This routine receives incoming data from the debug device.
  2945. Arguments:
  2946. Data - Supplies a pointer where the read data will be returned on success.
  2947. Size - Supplies a pointer that on input contains the size of the receive
  2948. buffer. On output, returns the number of bytes read.
  2949. Return Value:
  2950. STATUS_SUCCESS on success.
  2951. STATUS_NO_DATA_AVAILABLE if there was no data to be read at the current
  2952. time.
  2953. STATUS_DEVICE_IO_ERROR if a device error occurred.
  2954. --*/
  2955. {
  2956. KSTATUS Status;
  2957. KD_DEVICE_TRACE(KdDeviceTraceReceiving);
  2958. if (KdDebugDevice == NULL) {
  2959. Status = STATUS_NO_SUCH_DEVICE;
  2960. goto DeviceReceiveEnd;
  2961. }
  2962. Status = KdDebugDevice->FunctionTable.Receive(KdDebugDevice->Context,
  2963. Data,
  2964. Size);
  2965. DeviceReceiveEnd:
  2966. if (!KSUCCESS(Status)) {
  2967. KD_DEVICE_TRACE(KdDeviceTraceReceiveFailed);
  2968. } else {
  2969. KD_DEVICE_TRACE(KdDeviceTraceReceiveComplete);
  2970. }
  2971. return Status;
  2972. }
  2973. KSTATUS
  2974. KdpDeviceGetStatus (
  2975. PBOOL ReceiveDataAvailable
  2976. )
  2977. /*++
  2978. Routine Description:
  2979. This routine returns the current device status.
  2980. Arguments:
  2981. ReceiveDataAvailable - Supplies a pointer where a boolean will be returned
  2982. indicating whether or not receive data is available.
  2983. Return Value:
  2984. Status code.
  2985. --*/
  2986. {
  2987. KSTATUS Status;
  2988. KD_DEVICE_TRACE(KdDeviceTraceGettingStatus);
  2989. if (KdDebugDevice == NULL) {
  2990. Status = STATUS_NO_SUCH_DEVICE;
  2991. goto DeviceGetStatusEnd;
  2992. }
  2993. Status = KdDebugDevice->FunctionTable.GetStatus(KdDebugDevice->Context,
  2994. ReceiveDataAvailable);
  2995. DeviceGetStatusEnd:
  2996. if (!KSUCCESS(Status)) {
  2997. KD_DEVICE_TRACE(KdDeviceTraceGetStatusFailed);
  2998. } else {
  2999. if (*ReceiveDataAvailable != FALSE) {
  3000. KD_DEVICE_TRACE(KdDeviceTraceGetStatusHasData);
  3001. } else {
  3002. KD_DEVICE_TRACE(KdDeviceTraceGetStatusEmpty);
  3003. }
  3004. }
  3005. return Status;
  3006. }
  3007. VOID
  3008. KdpDeviceDisconnect (
  3009. VOID
  3010. )
  3011. /*++
  3012. Routine Description:
  3013. This routine disconnects a device, taking it offline.
  3014. Arguments:
  3015. None.
  3016. Return Value:
  3017. None.
  3018. --*/
  3019. {
  3020. KD_DEVICE_TRACE(KdDeviceTraceDisconnecting);
  3021. if (KdDebugDevice == NULL) {
  3022. goto DeviceDisconnectEnd;
  3023. }
  3024. KdDebugDevice->FunctionTable.Disconnect(KdDebugDevice->Context);
  3025. DeviceDisconnectEnd:
  3026. KD_DEVICE_TRACE(KdDeviceTraceDisconnected);
  3027. return;
  3028. }
  3029. VOID
  3030. KdpFreezeProcessors (
  3031. VOID
  3032. )
  3033. /*++
  3034. Routine Description:
  3035. This routine attempts to freeze all of the processors, assuming that the
  3036. current processor is the freeze owner. It sends an NMI IPI to all of the
  3037. other processors and waits for them to be marked frozen.
  3038. Arguments:
  3039. None.
  3040. Return Value:
  3041. None.
  3042. --*/
  3043. {
  3044. PROCESSOR_SET ProcessorSet;
  3045. KSTATUS Status;
  3046. ULONG Timeout;
  3047. ProcessorSet.Target = ProcessorTargetAllExcludingSelf;
  3048. Status = HlSendIpi(IpiTypeNmi, &ProcessorSet);
  3049. if (!KSUCCESS(Status)) {
  3050. goto FreezeProcessorsEnd;
  3051. }
  3052. Timeout = DEBUG_PROCESSOR_WAIT_TIME;
  3053. //
  3054. // Wait until all processors are frozen, or it's time to give
  3055. // up. Keep the time counter fresh too during this period.
  3056. //
  3057. KD_TRACE(KdTraceWaitingForFrozenProcessors);
  3058. while (KdProcessorsFrozen != KeActiveProcessorCount) {
  3059. if ((KdConnectionTimeout != MAX_ULONG) &&
  3060. (KdAvoidTimeCounter == FALSE)) {
  3061. if (Timeout == 0) {
  3062. break;
  3063. } else if (Timeout < DEBUG_STALL_INCREMENT) {
  3064. Timeout = DEBUG_STALL_INCREMENT;
  3065. }
  3066. HlBusySpin(DEBUG_STALL_INCREMENT);
  3067. Timeout -= DEBUG_STALL_INCREMENT;
  3068. }
  3069. if (KdAvoidTimeCounter == FALSE) {
  3070. HlQueryTimeCounter();
  3071. }
  3072. }
  3073. FreezeProcessorsEnd:
  3074. return;
  3075. }