extimp.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. extimp.c
  5. Abstract:
  6. This module implements the import library for debugger extensions. It is
  7. needed so that the extension doesn't link against a binary name directly
  8. (as there are several debugger client versions).
  9. Author:
  10. Evan Green 8-May-2013
  11. Environment:
  12. Debug Client
  13. --*/
  14. //
  15. // ------------------------------------------------------------------- Includes
  16. //
  17. #include <minoca/lib/types.h>
  18. #include <minoca/lib/status.h>
  19. #include <minoca/lib/rtl.h>
  20. #include <minoca/debug/dbgext.h>
  21. #include "extimp.h"
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. //
  29. // ----------------------------------------------- Internal Function Prototypes
  30. //
  31. //
  32. // -------------------------------------------------------------------- Globals
  33. //
  34. //
  35. // Store the import table.
  36. //
  37. PDEBUG_EXTENSION_IMPORT_INTERFACE DbgImportInterface;
  38. //
  39. // ------------------------------------------------------------------ Functions
  40. //
  41. __DLLEXPORT
  42. INT
  43. ExtensionEntry (
  44. ULONG ExtensionApiVersion,
  45. PDEBUGGER_CONTEXT ApplicationContext,
  46. PVOID Token,
  47. PDEBUG_EXTENSION_IMPORT_INTERFACE ImportInterface
  48. )
  49. /*++
  50. Routine Description:
  51. This routine defines the extension's internal entry point. This routine will
  52. get called when the extension is loaded. It is responsible for saving off
  53. the interface and then calling the debugger extension entry point.
  54. Arguments:
  55. ExtensionApiVersion - Supplies the revision of the debugger extension API.
  56. ApplicationContext - Supplies a pointer that represents the debugger
  57. application instance.
  58. Token - Supplies a token that uniquely idenfies the extension. This is used
  59. when registering extensions.
  60. ImportInterface - Supplies a pointer to the functions that the extension
  61. can call. This buffer will be constant, the extension does not need
  62. to make a copy of it.
  63. Return Value:
  64. 0 on success.
  65. Returns an error code on failure. The extension will be unloaded if it
  66. returns non-zero.
  67. --*/
  68. {
  69. //
  70. // Wire up the import interface, then call the extension.
  71. //
  72. DbgImportInterface = ImportInterface;
  73. return ExtensionMain(ApplicationContext, ExtensionApiVersion, Token);
  74. }
  75. INT
  76. DbgRegisterExtension (
  77. PDEBUGGER_CONTEXT Context,
  78. PVOID Token,
  79. PSTR ExtensionName,
  80. PSTR OneLineDescription,
  81. PEXTENSION_PROTOTYPE Routine
  82. )
  83. /*++
  84. Routine Description:
  85. This routine registers a debugger extension with the client.
  86. Arguments:
  87. Context - Supplies a pointer to the application context.
  88. Token - Supplies the unique token provided to the extension library upon
  89. initialization.
  90. ExtensionName - Supplies the name of the extension to register. This name
  91. must not already be registered by the current extension or any other.
  92. OneLineDescription - Supplies a quick description of the extension, no
  93. longer than 60 characters. This parameter is not optional.
  94. Routine - Supplies the routine to call when the given extension is
  95. invoked.
  96. Return Value:
  97. 0 on success.
  98. Returns an error code on failure.
  99. --*/
  100. {
  101. INT Result;
  102. Result = DbgImportInterface->RegisterExtension(Context,
  103. Token,
  104. ExtensionName,
  105. OneLineDescription,
  106. Routine);
  107. return Result;
  108. }
  109. INT
  110. DbgOut (
  111. const char *Format,
  112. ...
  113. )
  114. /*++
  115. Routine Description:
  116. This routine prints a formatted string to the debugger console.
  117. Arguments:
  118. Format - Supplies the printf format string.
  119. ... - Supplies a variable number of arguments, as required by the printf
  120. format string argument.
  121. Return Value:
  122. Returns the number of bytes successfully converted, not including the null
  123. terminator.
  124. Returns a negative number if an error was encountered.
  125. --*/
  126. {
  127. va_list Arguments;
  128. int Result;
  129. va_start(Arguments, Format);
  130. Result = DbgOutVaList(NULL, Format, Arguments);
  131. va_end(Arguments);
  132. return Result;
  133. }
  134. INT
  135. DbgOutVaList (
  136. PDEBUGGER_CONTEXT Context,
  137. const char *Format,
  138. va_list Arguments
  139. )
  140. /*++
  141. Routine Description:
  142. This routine prints a formatted string to the given debugger console.
  143. Arguments:
  144. Context - Supplies a pointer to the debugger context to output to.
  145. Format - Supplies the printf format string.
  146. Arguments - Supplies the argument list to the format string. The va_end
  147. macro is not invoked on this list.
  148. Return Value:
  149. Returns the number of bytes successfully converted. A null terminator is
  150. not written.
  151. Returns a negative number if an error was encountered.
  152. --*/
  153. {
  154. INT Result;
  155. Result = DbgImportInterface->OutVaList(Context, Format, Arguments);
  156. return Result;
  157. }
  158. INT
  159. DbgEvaluate (
  160. PDEBUGGER_CONTEXT Context,
  161. PSTR String,
  162. PULONGLONG Result
  163. )
  164. /*++
  165. Routine Description:
  166. This routine evaluates a mathematical expression. The following operators
  167. are supported: +, -, *, /, (, ). No spaces are permitted. Module symbols
  168. are permitted and will be translated into their corresponding address.
  169. Arguments:
  170. Context - Supplies a pointer to the debugger application context.
  171. String - Supplies the string to evaluate.
  172. Result - Supplies a pointer to the 64-bit unsigned integer where the result
  173. will be stored.
  174. Return Value:
  175. 0 if the expression was successfully evaluated.
  176. Returns an error code on failure.
  177. --*/
  178. {
  179. return DbgImportInterface->Evaluate(Context, String, Result);
  180. }
  181. INT
  182. DbgPrintAddressSymbol (
  183. PDEBUGGER_CONTEXT Context,
  184. ULONGLONG Address
  185. )
  186. /*++
  187. Routine Description:
  188. This routine prints a descriptive version of the given address, including
  189. the module and function name if possible.
  190. Arguments:
  191. Context - Supplies a pointer to the application context.
  192. Address - Supplies the virtual address of the target to print information
  193. about.
  194. Return Value:
  195. 0 if information was successfully printed.
  196. Returns an error code on failure.
  197. --*/
  198. {
  199. return DbgImportInterface->PrintAddressSymbol(Context, Address);
  200. }
  201. INT
  202. DbgReadMemory (
  203. PDEBUGGER_CONTEXT Context,
  204. BOOL VirtualMemory,
  205. ULONGLONG Address,
  206. ULONG BytesToRead,
  207. PVOID Buffer,
  208. PULONG BytesRead
  209. )
  210. /*++
  211. Routine Description:
  212. This routine retrieves the debuggee's memory.
  213. Arguments:
  214. Context - Supplies a pointer to the application context.
  215. VirtualMemory - Supplies a flag indicating whether the read should be
  216. virtual or physical.
  217. Address - Supplies the address to read from the target's memory.
  218. BytesToRead - Supplies the number of bytes to be read.
  219. Buffer - Supplies a pointer to the buffer where the memory contents will be
  220. returned.
  221. BytesRead - Supplies a pointer that receive the number of bytes that were
  222. actually read from the target.
  223. Return Value:
  224. 0 on success.
  225. Returns an error code on failure.
  226. --*/
  227. {
  228. INT Result;
  229. Result = DbgImportInterface->ReadMemory(Context,
  230. VirtualMemory,
  231. Address,
  232. BytesToRead,
  233. Buffer,
  234. BytesRead);
  235. return Result;
  236. }
  237. INT
  238. DbgWriteMemory (
  239. PDEBUGGER_CONTEXT Context,
  240. BOOL VirtualMemory,
  241. ULONGLONG Address,
  242. ULONG BytesToWrite,
  243. PVOID Buffer,
  244. PULONG BytesWritten
  245. )
  246. /*++
  247. Routine Description:
  248. This routine writes to the debuggee's memory.
  249. Arguments:
  250. Context - Supplies a pointer to the application context.
  251. VirtualMemory - Supplies a flag indicating whether the read should be
  252. virtual or physical.
  253. Address - Supplies the address to write to the target's memory.
  254. BytesToWrite - Supplies the number of bytes to be written.
  255. Buffer - Supplies a pointer to the buffer containing the values to write.
  256. BytesWritten - Supplies a pointer that receives the number of bytes that
  257. were actually written to the target.
  258. Return Value:
  259. 0 if the write was successful.
  260. Returns an error code on failure.
  261. --*/
  262. {
  263. INT Result;
  264. Result = DbgImportInterface->WriteMemory(Context,
  265. VirtualMemory,
  266. Address,
  267. BytesToWrite,
  268. Buffer,
  269. BytesWritten);
  270. return Result;
  271. }
  272. INT
  273. DbgReboot (
  274. PDEBUGGER_CONTEXT Context,
  275. ULONG RebootType
  276. )
  277. /*++
  278. Routine Description:
  279. This routine attempts to reboot the target machine.
  280. Arguments:
  281. Context - Supplies a pointer to the application context.
  282. RebootType - Supplies the type of reboot to perform. See the
  283. DEBUG_REBOOT_TYPE enumeration.
  284. Return Value:
  285. 0 if the write was successful.
  286. Returns an error code on failure.
  287. --*/
  288. {
  289. INT Result;
  290. Result = DbgImportInterface->Reboot(Context, RebootType);
  291. return Result;
  292. }
  293. INT
  294. DbgGetCallStack (
  295. PDEBUGGER_CONTEXT Context,
  296. PREGISTERS_UNION Registers,
  297. PSTACK_FRAME Frames,
  298. PULONG FrameCount
  299. )
  300. /*++
  301. Routine Description:
  302. This routine attempts to unwind the call stack starting at the given
  303. machine state.
  304. Arguments:
  305. Context - Supplies a pointer to the application context.
  306. Registers - Supplies an optional pointer to the registers on input. On
  307. output, these registers will be updated with the unwound value. If this
  308. is NULL, then the current break notification registers will be used.
  309. Frames - Supplies a pointer where the array of stack frames will be
  310. returned.
  311. FrameCount - Supplies the number of frames allocated in the frames
  312. argument, representing the maximum number of frames to get. On output,
  313. returns the number of valid frames in the array.
  314. Return Value:
  315. 0 on success.
  316. Returns an error code on failure.
  317. --*/
  318. {
  319. INT Result;
  320. Result = DbgImportInterface->GetCallStack(Context,
  321. Registers,
  322. Frames,
  323. FrameCount);
  324. return Result;
  325. }
  326. INT
  327. DbgPrintCallStack (
  328. PDEBUGGER_CONTEXT Context,
  329. PREGISTERS_UNION Registers,
  330. BOOL PrintFrameNumbers
  331. )
  332. /*++
  333. Routine Description:
  334. This routine prints a call stack starting with the given registers.
  335. Arguments:
  336. Context - Supplies a pointer to the application context.
  337. Registers - Supplies an optional pointer to the registers to use when
  338. unwinding.
  339. PrintFrameNumbers - Supplies a boolean indicating whether or not frame
  340. numbers should be printed to the left of every frame.
  341. Return Value:
  342. 0 on success.
  343. Returns an error code on failure.
  344. --*/
  345. {
  346. INT Result;
  347. Result = DbgImportInterface->PrintCallStack(Context,
  348. Registers,
  349. PrintFrameNumbers);
  350. return Result;
  351. }
  352. INT
  353. DbgGetTargetInformation (
  354. PDEBUGGER_CONTEXT Context,
  355. PDEBUG_TARGET_INFORMATION TargetInformation,
  356. ULONG TargetInformationSize
  357. )
  358. /*++
  359. Routine Description:
  360. This routine returns information about the machine being debugged.
  361. Arguments:
  362. Context - Supplies a pointer to the application context.
  363. TargetInformation - Supplies a pointer where the target information will
  364. be returned.
  365. TargetInformationSize - Supplies the size of the target information buffer.
  366. This must be the size of a debug target information structure.
  367. Return Value:
  368. 0 on success.
  369. Returns an error code on failure.
  370. --*/
  371. {
  372. INT Result;
  373. Result = DbgImportInterface->GetTargetInformation(Context,
  374. TargetInformation,
  375. TargetInformationSize);
  376. return Result;
  377. }
  378. ULONG
  379. DbgGetTargetPointerSize (
  380. PDEBUGGER_CONTEXT Context
  381. )
  382. /*++
  383. Routine Description:
  384. This routine returns the size of a pointer on the target machine, in bytes.
  385. Arguments:
  386. Context - Supplies a pointer to the application context.
  387. Return Value:
  388. The size of a pointer on the target system, in bytes.
  389. --*/
  390. {
  391. return DbgImportInterface->GetTargetPointerSize(Context);
  392. }
  393. INT
  394. DbgGetMemberOffset (
  395. PTYPE_SYMBOL StructureType,
  396. PSTR FieldName,
  397. PULONG FieldOffset,
  398. PULONG FieldSize
  399. )
  400. /*++
  401. Routine Description:
  402. This routine returns the given field's offset (in bits) within the
  403. given structure.
  404. Arguments:
  405. StructureType - Supplies a pointer to a symbol structure type.
  406. FieldName - Supplies a string containing the name of the field whose offset
  407. will be returned.
  408. FieldOffset - Supplies a pointer that will receive the bit offset of the
  409. given field name within the given structure.
  410. FieldSize - Supplies a pointer that will receive the size of the field in
  411. bits.
  412. Return Value:
  413. 0 on success.
  414. ENOENT if no such field name exists.
  415. Other error codes on other errors.
  416. --*/
  417. {
  418. INT Result;
  419. Result = DbgImportInterface->GetMemberOffset(StructureType,
  420. FieldName,
  421. FieldOffset,
  422. FieldSize);
  423. return Result;
  424. }
  425. INT
  426. DbgGetTypeByName (
  427. PDEBUGGER_CONTEXT Context,
  428. PSTR TypeName,
  429. PTYPE_SYMBOL *Type
  430. )
  431. /*++
  432. Routine Description:
  433. This routine finds a type symbol object by its type name.
  434. Arguments:
  435. Context - Supplies a pointer to the application context.
  436. TypeName - Supplies a pointer to the string containing the name of the
  437. type to find. This can be prefixed with an module name if needed.
  438. Type - Supplies a pointer where a pointer to the type will be returned.
  439. Return Value:
  440. 0 on success.
  441. ENOENT if no type with the given name was found.
  442. Returns an error number on failure.
  443. --*/
  444. {
  445. INT Status;
  446. Status = DbgImportInterface->GetTypeByName(Context, TypeName, Type);
  447. return Status;
  448. }
  449. INT
  450. DbgReadIntegerMember (
  451. PDEBUGGER_CONTEXT Context,
  452. PTYPE_SYMBOL Type,
  453. PSTR MemberName,
  454. ULONGLONG Address,
  455. PVOID Data,
  456. ULONG DataSize,
  457. PULONGLONG Value
  458. )
  459. /*++
  460. Routine Description:
  461. This routine reads an integer sized member out of an already read-in
  462. structure.
  463. Arguments:
  464. Context - Supplies a pointer to the application context.
  465. Type - Supplies a pointer to the type of the data.
  466. MemberName - Supplies a pointer to the member name.
  467. Address - Supplies the address where the data was obtained.
  468. Data - Supplies a pointer to the data contents.
  469. DataSize - Supplies the size of the data buffer in bytes.
  470. Value - Supplies a pointer where the value will be returned on success.
  471. Return Value:
  472. 0 on success.
  473. Returns an error number on failure.
  474. --*/
  475. {
  476. INT Status;
  477. Status = DbgImportInterface->ReadIntegerMember(Context,
  478. Type,
  479. MemberName,
  480. Address,
  481. Data,
  482. DataSize,
  483. Value);
  484. return Status;
  485. }
  486. INT
  487. DbgReadTypeByName (
  488. PDEBUGGER_CONTEXT Context,
  489. ULONGLONG Address,
  490. PSTR TypeName,
  491. PTYPE_SYMBOL *FinalType,
  492. PVOID *Data,
  493. PULONG DataSize
  494. )
  495. /*++
  496. Routine Description:
  497. This routine reads in data from the target for a specified type, which is
  498. given as a string.
  499. Arguments:
  500. Context - Supplies a pointer to the application context.
  501. Address - Supplies a target address pointer where the data resides.
  502. TypeName - Supplies a pointer to a string containing the type name to get.
  503. This should start with a type name, and can use dot '.' notation to
  504. specify field members, and array[] notation to specify dereferences.
  505. FinalType - Supplies a pointer where the final type symbol will be returned
  506. on success.
  507. Data - Supplies a pointer where the data will be returned on success. The
  508. caller is responsible for freeing this data when finished.
  509. DataSize - Supplies a pointer where the size of the data in bytes will be
  510. returned.
  511. Return Value:
  512. 0 on success.
  513. Returns an error number on failure.
  514. --*/
  515. {
  516. INT Status;
  517. Status = DbgImportInterface->ReadTypeByName(Context,
  518. Address,
  519. TypeName,
  520. FinalType,
  521. Data,
  522. DataSize);
  523. return Status;
  524. }
  525. INT
  526. DbgReadType (
  527. PDEBUGGER_CONTEXT Context,
  528. ULONGLONG Address,
  529. PTYPE_SYMBOL Type,
  530. PVOID *Data,
  531. PULONG DataSize
  532. )
  533. /*++
  534. Routine Description:
  535. This routine reads in data from the target for a specified type.
  536. Arguments:
  537. Context - Supplies a pointer to the application context.
  538. Address - Supplies a target address pointer where the data resides.
  539. Type - Supplies a pointer to the type symbol to get.
  540. Data - Supplies a pointer where the data will be returned on success. The
  541. caller is responsible for freeing this data when finished.
  542. DataSize - Supplies a pointer where the size of the data in bytes will be
  543. returned.
  544. Return Value:
  545. 0 on success.
  546. Returns an error number on failure.
  547. --*/
  548. {
  549. INT Status;
  550. Status = DbgImportInterface->ReadType(Context,
  551. Address,
  552. Type,
  553. Data,
  554. DataSize);
  555. return Status;
  556. }
  557. INT
  558. DbgPrintTypeMember (
  559. PDEBUGGER_CONTEXT Context,
  560. ULONGLONG Address,
  561. PVOID Data,
  562. ULONG DataSize,
  563. PTYPE_SYMBOL Type,
  564. PSTR MemberName,
  565. ULONG SpaceLevel,
  566. ULONG RecursionCount
  567. )
  568. /*++
  569. Routine Description:
  570. This routine prints a member of a structure or union whose contents have
  571. already been read in.
  572. Arguments:
  573. Context - Supplies a pointer to the application context.
  574. Address - Supplies the address where this data came from.
  575. Data - Supplies a pointer to the data contents.
  576. DataSize - Supplies the size of the data contents buffer in bytes.
  577. Type - Supplies a pointer to the structure type.
  578. MemberName - Supplies the name of the member to print.
  579. SpaceLevel - Supplies the number of spaces worth of indentation to print
  580. for subsequent lines.
  581. RecursionCount - Supplies the number of substructures to recurse into.
  582. Return Value:
  583. 0 on success.
  584. Returns an error number on failure.
  585. --*/
  586. {
  587. INT Status;
  588. Status = DbgImportInterface->PrintTypeMember(Context,
  589. Address,
  590. Data,
  591. DataSize,
  592. Type,
  593. MemberName,
  594. SpaceLevel,
  595. RecursionCount);
  596. return Status;
  597. }
  598. //
  599. // --------------------------------------------------------- Internal Functions
  600. //