types.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  1. /*
  2. * File types.c - datatype handling stuff for internal debugger.
  3. *
  4. * Copyright (C) 1997, Eric Youngdale.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. *
  20. * Note: This really doesn't do much at the moment, but it forms the framework
  21. * upon which full support for datatype handling will eventually be built.
  22. */
  23. #include <stdlib.h>
  24. #include "debugger.h"
  25. #include "wine/debug.h"
  26. WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
  27. /******************************************************************
  28. * types_get_real_type
  29. *
  30. * Get rid of any potential typedef in the lvalue's type to get
  31. * to the 'real' type (the one we can work upon).
  32. */
  33. BOOL types_get_real_type(struct dbg_type* type, DWORD* tag)
  34. {
  35. if (type->id == dbg_itype_none) return FALSE;
  36. do
  37. {
  38. if (!types_get_info(type, TI_GET_SYMTAG, tag))
  39. return FALSE;
  40. if (*tag != SymTagTypedef) return TRUE;
  41. } while (types_get_info(type, TI_GET_TYPE, &type->id));
  42. return FALSE;
  43. }
  44. /******************************************************************
  45. * types_extract_as_lgint
  46. *
  47. * Given a lvalue, try to get an integral (or pointer/address) value
  48. * out of it
  49. */
  50. dbg_lgint_t types_extract_as_lgint(const struct dbg_lvalue* lvalue,
  51. unsigned* psize, BOOL *issigned)
  52. {
  53. dbg_lgint_t rtn = 0;
  54. DWORD tag, bt;
  55. DWORD64 size;
  56. struct dbg_type type = lvalue->type;
  57. BOOL s = FALSE;
  58. if (!types_get_real_type(&type, &tag))
  59. RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
  60. if (type.id == dbg_itype_segptr)
  61. {
  62. return (LONG_PTR)memory_to_linear_addr(&lvalue->addr);
  63. }
  64. if (tag != SymTagBaseType && lvalue->bitlen) dbg_printf("Unexpected bitfield on tag %d\n", tag);
  65. if (psize) *psize = 0;
  66. if (issigned) *issigned = FALSE;
  67. switch (tag)
  68. {
  69. case SymTagBaseType:
  70. if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
  71. !types_get_info(&type, TI_GET_BASETYPE, &bt))
  72. {
  73. WINE_ERR("Couldn't get information\n");
  74. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  75. return rtn;
  76. }
  77. if (size > sizeof(rtn))
  78. {
  79. WINE_ERR("Size too large (%I64x)\n", size);
  80. RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
  81. return rtn;
  82. }
  83. switch (bt)
  84. {
  85. case btChar:
  86. case btInt:
  87. if (!memory_fetch_integer(lvalue, (unsigned)size, s = TRUE, &rtn))
  88. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  89. break;
  90. case btUInt:
  91. if (!memory_fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
  92. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  93. break;
  94. case btFloat:
  95. RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
  96. }
  97. if (psize) *psize = (unsigned)size;
  98. if (issigned) *issigned = s;
  99. break;
  100. case SymTagPointerType:
  101. if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
  102. !memory_fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
  103. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  104. break;
  105. case SymTagArrayType:
  106. case SymTagUDT:
  107. if (!memory_fetch_integer(lvalue, sizeof(unsigned), s = FALSE, &rtn))
  108. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  109. break;
  110. case SymTagEnum:
  111. if (!types_get_info(&type, TI_GET_LENGTH, &size) ||
  112. !memory_fetch_integer(lvalue, (unsigned)size, s = FALSE, &rtn))
  113. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  114. break;
  115. case SymTagFunctionType:
  116. rtn = (ULONG_PTR)memory_to_linear_addr(&lvalue->addr);
  117. break;
  118. default:
  119. WINE_FIXME("Unsupported tag %u\n", tag);
  120. RaiseException(DEBUG_STATUS_NOT_AN_INTEGER, 0, 0, NULL);
  121. }
  122. return rtn;
  123. }
  124. /******************************************************************
  125. * types_extract_as_integer
  126. *
  127. * Given a lvalue, try to get an integral (or pointer/address) value
  128. * out of it
  129. */
  130. dbg_lgint_t types_extract_as_integer(const struct dbg_lvalue* lvalue)
  131. {
  132. return types_extract_as_lgint(lvalue, NULL, NULL);
  133. }
  134. /******************************************************************
  135. * types_extract_as_address
  136. *
  137. *
  138. */
  139. void types_extract_as_address(const struct dbg_lvalue* lvalue, ADDRESS64* addr)
  140. {
  141. if (lvalue->type.id == dbg_itype_segptr && lvalue->type.module == 0)
  142. {
  143. *addr = lvalue->addr;
  144. }
  145. else
  146. {
  147. addr->Mode = AddrModeFlat;
  148. addr->Offset = types_extract_as_lgint(lvalue, NULL, NULL);
  149. }
  150. }
  151. BOOL types_store_value(struct dbg_lvalue* lvalue_to, const struct dbg_lvalue* lvalue_from)
  152. {
  153. if (!lvalue_to->bitlen && !lvalue_from->bitlen)
  154. {
  155. BOOL equal;
  156. if (!types_compare(lvalue_to->type, lvalue_from->type, &equal)) return FALSE;
  157. if (equal)
  158. return memory_transfer_value(lvalue_to, lvalue_from);
  159. if (types_is_float_type(lvalue_from) && types_is_float_type(lvalue_to))
  160. {
  161. double d;
  162. return memory_fetch_float(lvalue_from, &d) &&
  163. memory_store_float(lvalue_to, &d);
  164. }
  165. }
  166. if (types_is_integral_type(lvalue_from) && types_is_integral_type(lvalue_to))
  167. {
  168. /* doing integer conversion (about sign, size) */
  169. dbg_lgint_t val = types_extract_as_integer(lvalue_from);
  170. return memory_store_integer(lvalue_to, val);
  171. }
  172. dbg_printf("Cannot assign (different types)\n"); return FALSE;
  173. return FALSE;
  174. }
  175. /******************************************************************
  176. * types_get_udt_element_lvalue
  177. *
  178. * Implement a structure derefencement
  179. */
  180. static BOOL types_get_udt_element_lvalue(struct dbg_lvalue* lvalue, const struct dbg_type* type)
  181. {
  182. DWORD offset, bitoffset;
  183. DWORD64 length;
  184. types_get_info(type, TI_GET_TYPE, &lvalue->type.id);
  185. lvalue->type.module = type->module;
  186. if (!types_get_info(type, TI_GET_OFFSET, &offset)) return FALSE;
  187. lvalue->addr.Offset += offset;
  188. if (types_get_info(type, TI_GET_BITPOSITION, &bitoffset))
  189. {
  190. types_get_info(type, TI_GET_LENGTH, &length);
  191. lvalue->bitlen = length;
  192. lvalue->bitstart = bitoffset;
  193. if (lvalue->bitlen != length || lvalue->bitstart != bitoffset)
  194. {
  195. dbg_printf("too wide bitfields\n"); /* shouldn't happen */
  196. return FALSE;
  197. }
  198. }
  199. else
  200. lvalue->bitlen = lvalue->bitstart = 0;
  201. return TRUE;
  202. }
  203. /******************************************************************
  204. * types_udt_find_element
  205. *
  206. */
  207. BOOL types_udt_find_element(struct dbg_lvalue* lvalue, const char* name)
  208. {
  209. DWORD tag, count;
  210. char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
  211. TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
  212. WCHAR* ptr;
  213. char tmp[256];
  214. struct dbg_type type;
  215. if (!types_get_real_type(&lvalue->type, &tag) || tag != SymTagUDT)
  216. return FALSE;
  217. if (types_get_info(&lvalue->type, TI_GET_CHILDRENCOUNT, &count))
  218. {
  219. fcp->Start = 0;
  220. while (count)
  221. {
  222. fcp->Count = min(count, 256);
  223. if (types_get_info(&lvalue->type, TI_FINDCHILDREN, fcp))
  224. {
  225. unsigned i;
  226. type.module = lvalue->type.module;
  227. for (i = 0; i < min(fcp->Count, count); i++)
  228. {
  229. type.id = fcp->ChildId[i];
  230. if (types_get_info(&type, TI_GET_SYMNAME, &ptr) && ptr)
  231. {
  232. WideCharToMultiByte(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp), NULL, NULL);
  233. HeapFree(GetProcessHeap(), 0, ptr);
  234. if (!strcmp(tmp, name))
  235. return types_get_udt_element_lvalue(lvalue, &type);
  236. }
  237. }
  238. }
  239. count -= min(count, 256);
  240. fcp->Start += 256;
  241. }
  242. }
  243. return FALSE;
  244. }
  245. /******************************************************************
  246. * types_array_index
  247. *
  248. * Grab an element from an array
  249. */
  250. BOOL types_array_index(const struct dbg_lvalue* lvalue, int index, struct dbg_lvalue* result)
  251. {
  252. struct dbg_type type = lvalue->type;
  253. DWORD tag, count;
  254. memset(result, 0, sizeof(*result));
  255. result->type.id = dbg_itype_none;
  256. result->type.module = 0;
  257. if (!types_get_real_type(&type, &tag)) return FALSE;
  258. switch (tag)
  259. {
  260. case SymTagArrayType:
  261. if (!types_get_info(&type, TI_GET_COUNT, &count)) return FALSE;
  262. if (index < 0 || index >= count) return FALSE;
  263. result->addr = lvalue->addr;
  264. break;
  265. case SymTagPointerType:
  266. if (!memory_read_value(lvalue, dbg_curr_process->be_cpu->pointer_size, &result->addr.Offset))
  267. return FALSE;
  268. result->addr.Mode = AddrModeFlat;
  269. switch (dbg_curr_process->be_cpu->pointer_size)
  270. {
  271. case 4: result->addr.Offset = (DWORD)result->addr.Offset; break;
  272. case 8: break;
  273. default: assert(0);
  274. }
  275. break;
  276. default:
  277. assert(FALSE);
  278. }
  279. /*
  280. * Get the base type, so we know how much to index by.
  281. */
  282. if (!types_get_info(&type, TI_GET_TYPE, &result->type.id)) return FALSE;
  283. result->type.module = type.module;
  284. if (index)
  285. {
  286. DWORD64 length;
  287. if (!types_get_info(&result->type, TI_GET_LENGTH, &length)) return FALSE;
  288. result->addr.Offset += index * (DWORD)length;
  289. }
  290. /* FIXME: the following statement is not always true (and can lead to buggy behavior).
  291. * There is no way to tell where the deref:ed value is...
  292. * For example:
  293. * x is a pointer to struct s, x being on the stack
  294. * => lvalue is in debuggee, result is in debugger
  295. * x is a pointer to struct s, x being optimized into a reg
  296. * => lvalue is debugger, result is debuggee
  297. * x is a pointer to internal variable x
  298. * => lvalue is debugger, result is debuggee
  299. * So we always force debuggee address space, because dereferencing pointers to
  300. * internal variables is very unlikely. A correct fix would be
  301. * rather large.
  302. */
  303. result->in_debuggee = 1;
  304. return TRUE;
  305. }
  306. struct type_find_t
  307. {
  308. ULONG result; /* out: the found type */
  309. enum SymTagEnum tag; /* in: the tag to look for */
  310. union
  311. {
  312. ULONG typeid; /* when tag is SymTagUDT */
  313. const char* name; /* when tag is SymTagPointerType */
  314. } u;
  315. };
  316. static BOOL CALLBACK types_cb(PSYMBOL_INFO sym, ULONG size, void* _user)
  317. {
  318. struct type_find_t* user = _user;
  319. BOOL ret = TRUE;
  320. struct dbg_type type;
  321. DWORD type_id;
  322. if (sym->Tag == user->tag)
  323. {
  324. switch (user->tag)
  325. {
  326. case SymTagUDT:
  327. if (!strcmp(user->u.name, sym->Name))
  328. {
  329. user->result = sym->TypeIndex;
  330. ret = FALSE;
  331. }
  332. break;
  333. case SymTagPointerType:
  334. type.module = sym->ModBase;
  335. type.id = sym->TypeIndex;
  336. if (types_get_info(&type, TI_GET_TYPE, &type_id) && type_id == user->u.typeid)
  337. {
  338. user->result = sym->TypeIndex;
  339. ret = FALSE;
  340. }
  341. break;
  342. default: break;
  343. }
  344. }
  345. return ret;
  346. }
  347. /******************************************************************
  348. * types_find_pointer
  349. *
  350. * Should look up in module based at linear whether (typeid*) exists
  351. * Otherwise, we could create it locally
  352. */
  353. struct dbg_type types_find_pointer(const struct dbg_type* type)
  354. {
  355. struct type_find_t f;
  356. struct dbg_type ret;
  357. f.result = dbg_itype_none;
  358. f.tag = SymTagPointerType;
  359. f.u.typeid = type->id;
  360. SymEnumTypes(dbg_curr_process->handle, type->module, types_cb, &f);
  361. ret.module = type->module;
  362. ret.id = f.result;
  363. return ret;
  364. }
  365. /******************************************************************
  366. * types_find_type
  367. *
  368. * Should look up in the module based at linear address whether a type
  369. * named 'name' and with the correct tag exists
  370. */
  371. struct dbg_type types_find_type(DWORD64 linear, const char* name, enum SymTagEnum tag)
  372. {
  373. struct type_find_t f;
  374. struct dbg_type ret;
  375. f.result = dbg_itype_none;
  376. f.tag = tag;
  377. f.u.name = name;
  378. SymEnumTypes(dbg_curr_process->handle, linear, types_cb, &f);
  379. ret.module = linear;
  380. ret.id = f.result;
  381. return ret;
  382. }
  383. /***********************************************************************
  384. * print_value
  385. *
  386. * Implementation of the 'print' command.
  387. */
  388. void print_value(const struct dbg_lvalue* lvalue, char format, int level)
  389. {
  390. struct dbg_type type = lvalue->type;
  391. struct dbg_lvalue lvalue_field;
  392. int i;
  393. DWORD tag;
  394. DWORD count;
  395. DWORD64 size;
  396. if (!types_get_real_type(&type, &tag))
  397. {
  398. WINE_FIXME("---error\n");
  399. return;
  400. }
  401. if (type.id == dbg_itype_none)
  402. {
  403. /* No type, just print the addr value */
  404. print_bare_address(&lvalue->addr);
  405. goto leave;
  406. }
  407. if (format == 'i' || format == 's' || format == 'w' || format == 'b' || format == 'g')
  408. {
  409. dbg_printf("Format specifier '%c' is meaningless in 'print' command\n", format);
  410. format = '\0';
  411. }
  412. switch (tag)
  413. {
  414. case SymTagBaseType:
  415. case SymTagEnum:
  416. case SymTagPointerType:
  417. /* FIXME: this in not 100% optimal (as we're going through the typedef handling
  418. * stuff again
  419. */
  420. print_basic(lvalue, format);
  421. break;
  422. case SymTagUDT:
  423. if (types_get_info(&type, TI_GET_CHILDRENCOUNT, &count))
  424. {
  425. char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
  426. TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
  427. WCHAR* ptr;
  428. struct dbg_type sub_type;
  429. dbg_printf("{");
  430. fcp->Start = 0;
  431. while (count)
  432. {
  433. fcp->Count = min(count, 256);
  434. if (types_get_info(&type, TI_FINDCHILDREN, fcp))
  435. {
  436. for (i = 0; i < min(fcp->Count, count); i++)
  437. {
  438. sub_type.module = type.module;
  439. sub_type.id = fcp->ChildId[i];
  440. if (!types_get_info(&sub_type, TI_GET_SYMNAME, &ptr) || !ptr) continue;
  441. dbg_printf("%ls=", ptr);
  442. HeapFree(GetProcessHeap(), 0, ptr);
  443. lvalue_field = *lvalue;
  444. if (types_get_udt_element_lvalue(&lvalue_field, &sub_type))
  445. {
  446. print_value(&lvalue_field, format, level + 1);
  447. }
  448. if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
  449. }
  450. }
  451. count -= min(count, 256);
  452. fcp->Start += 256;
  453. }
  454. dbg_printf("}");
  455. }
  456. break;
  457. case SymTagArrayType:
  458. /*
  459. * Loop over all of the entries, printing stuff as we go.
  460. */
  461. count = 1; size = 1;
  462. types_get_info(&type, TI_GET_COUNT, &count);
  463. types_get_info(&type, TI_GET_LENGTH, &size);
  464. lvalue_field = *lvalue;
  465. types_get_info(&lvalue_field.type, TI_GET_TYPE, &lvalue_field.type.id);
  466. types_get_real_type(&lvalue_field.type, &tag);
  467. if (size == count && tag == SymTagBaseType)
  468. {
  469. DWORD basetype;
  470. types_get_info(&lvalue_field.type, TI_GET_BASETYPE, &basetype);
  471. if (basetype == btChar)
  472. {
  473. char buffer[256];
  474. /*
  475. * Special handling for character arrays.
  476. */
  477. unsigned len = min(count, sizeof(buffer));
  478. memory_get_string(dbg_curr_process,
  479. memory_to_linear_addr(&lvalue->addr),
  480. lvalue->in_debuggee, TRUE, buffer, len);
  481. dbg_printf("\"%s%s\"", buffer, (len < count) ? "..." : "");
  482. break;
  483. }
  484. }
  485. dbg_printf("{");
  486. for (i = 0; i < count; i++)
  487. {
  488. print_value(&lvalue_field, format, level + 1);
  489. lvalue_field.addr.Offset += size / count;
  490. dbg_printf((i == count - 1) ? "}" : ", ");
  491. }
  492. break;
  493. case SymTagFunctionType:
  494. dbg_printf("Function ");
  495. print_bare_address(&lvalue->addr);
  496. dbg_printf(": ");
  497. types_print_type(&type, FALSE);
  498. break;
  499. case SymTagTypedef:
  500. lvalue_field = *lvalue;
  501. types_get_info(&lvalue->type, TI_GET_TYPE, &lvalue_field.type.id);
  502. print_value(&lvalue_field, format, level);
  503. break;
  504. default:
  505. WINE_FIXME("Unknown tag (%u)\n", tag);
  506. RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
  507. break;
  508. }
  509. leave:
  510. if (level == 0) dbg_printf("\n");
  511. }
  512. static BOOL CALLBACK print_types_cb(PSYMBOL_INFO sym, ULONG size, void* ctx)
  513. {
  514. struct dbg_type type;
  515. type.module = sym->ModBase;
  516. type.id = sym->TypeIndex;
  517. dbg_printf("Mod: %0*Ix ID: %08x\n", ADDRWIDTH, type.module, type.id);
  518. types_print_type(&type, TRUE);
  519. dbg_printf("\n");
  520. return TRUE;
  521. }
  522. static BOOL CALLBACK print_types_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx)
  523. {
  524. return SymEnumTypes(dbg_curr_process->handle, base, print_types_cb, ctx);
  525. }
  526. BOOL print_types(void)
  527. {
  528. if (!dbg_curr_process)
  529. {
  530. dbg_printf("No known process, cannot print types\n");
  531. return FALSE;
  532. }
  533. SymEnumerateModules64(dbg_curr_process->handle, print_types_mod_cb, NULL);
  534. return FALSE;
  535. }
  536. BOOL types_print_type(const struct dbg_type* type, BOOL details)
  537. {
  538. WCHAR* ptr;
  539. const WCHAR* name;
  540. DWORD tag, udt, count;
  541. struct dbg_type subtype;
  542. if (type->id == dbg_itype_none || !types_get_info(type, TI_GET_SYMTAG, &tag))
  543. {
  544. dbg_printf("--invalid--<%xh>--", type->id);
  545. return FALSE;
  546. }
  547. name = (types_get_info(type, TI_GET_SYMNAME, &ptr) && ptr) ? ptr : L"--none--";
  548. switch (tag)
  549. {
  550. case SymTagBaseType:
  551. if (details) dbg_printf("Basic<%ls>", name); else dbg_printf("%ls", name);
  552. break;
  553. case SymTagPointerType:
  554. types_get_info(type, TI_GET_TYPE, &subtype.id);
  555. subtype.module = type->module;
  556. types_print_type(&subtype, FALSE);
  557. dbg_printf("*");
  558. break;
  559. case SymTagUDT:
  560. types_get_info(type, TI_GET_UDTKIND, &udt);
  561. switch (udt)
  562. {
  563. case UdtStruct: dbg_printf("struct %ls", name); break;
  564. case UdtUnion: dbg_printf("union %ls", name); break;
  565. case UdtClass: dbg_printf("class %ls", name); break;
  566. default: WINE_ERR("Unsupported UDT type (%d) for %ls\n", udt, name); break;
  567. }
  568. if (details &&
  569. types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
  570. {
  571. char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
  572. TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
  573. WCHAR* ptr;
  574. int i;
  575. struct dbg_type type_elt;
  576. dbg_printf(" {");
  577. fcp->Start = 0;
  578. while (count)
  579. {
  580. fcp->Count = min(count, 256);
  581. if (types_get_info(type, TI_FINDCHILDREN, fcp))
  582. {
  583. for (i = 0; i < min(fcp->Count, count); i++)
  584. {
  585. type_elt.module = type->module;
  586. type_elt.id = fcp->ChildId[i];
  587. if (!types_get_info(&type_elt, TI_GET_SYMNAME, &ptr) || !ptr) continue;
  588. dbg_printf("%ls", ptr);
  589. HeapFree(GetProcessHeap(), 0, ptr);
  590. if (types_get_info(&type_elt, TI_GET_TYPE, &type_elt.id))
  591. {
  592. dbg_printf(":");
  593. types_print_type(&type_elt, details);
  594. }
  595. if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
  596. }
  597. }
  598. count -= min(count, 256);
  599. fcp->Start += 256;
  600. }
  601. dbg_printf("}");
  602. }
  603. break;
  604. case SymTagArrayType:
  605. types_get_info(type, TI_GET_TYPE, &subtype.id);
  606. subtype.module = type->module;
  607. types_print_type(&subtype, details);
  608. if (types_get_info(type, TI_GET_COUNT, &count))
  609. dbg_printf(" %ls[%d]", name, count);
  610. else
  611. dbg_printf(" %ls[]", name);
  612. break;
  613. case SymTagEnum:
  614. dbg_printf("enum %ls", name);
  615. break;
  616. case SymTagFunctionType:
  617. types_get_info(type, TI_GET_TYPE, &subtype.id);
  618. /* is the returned type the same object as function sig itself ? */
  619. if (subtype.id != type->id)
  620. {
  621. subtype.module = type->module;
  622. types_print_type(&subtype, FALSE);
  623. }
  624. else
  625. {
  626. subtype.module = 0;
  627. dbg_printf("<ret_type=self>");
  628. }
  629. dbg_printf(" (*%ls)(", name);
  630. if (types_get_info(type, TI_GET_CHILDRENCOUNT, &count))
  631. {
  632. char buffer[sizeof(TI_FINDCHILDREN_PARAMS) + 256 * sizeof(DWORD)];
  633. TI_FINDCHILDREN_PARAMS* fcp = (TI_FINDCHILDREN_PARAMS*)buffer;
  634. int i;
  635. fcp->Start = 0;
  636. if (!count) dbg_printf("void");
  637. else while (count)
  638. {
  639. fcp->Count = min(count, 256);
  640. if (types_get_info(type, TI_FINDCHILDREN, fcp))
  641. {
  642. for (i = 0; i < min(fcp->Count, count); i++)
  643. {
  644. subtype.id = fcp->ChildId[i];
  645. types_get_info(&subtype, TI_GET_TYPE, &subtype.id);
  646. types_print_type(&subtype, FALSE);
  647. if (i < min(fcp->Count, count) - 1 || count > 256) dbg_printf(", ");
  648. }
  649. }
  650. count -= min(count, 256);
  651. fcp->Start += 256;
  652. }
  653. }
  654. dbg_printf(")");
  655. break;
  656. case SymTagTypedef:
  657. dbg_printf("%ls", name);
  658. break;
  659. default:
  660. WINE_ERR("Unknown type %u for %ls\n", tag, name);
  661. break;
  662. }
  663. HeapFree(GetProcessHeap(), 0, ptr);
  664. return TRUE;
  665. }
  666. /* helper to typecast pInfo to its expected type (_t) */
  667. #define X(_t) (*((_t*)pInfo))
  668. BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, void* pInfo)
  669. {
  670. if (type->id == dbg_itype_none) return FALSE;
  671. if (type->module != 0)
  672. {
  673. DWORD ret, tag, bt;
  674. ret = SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, ti, pInfo);
  675. if (!ret &&
  676. ti == TI_GET_SYMNAME &&
  677. SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_SYMTAG, &tag) &&
  678. tag == SymTagBaseType &&
  679. SymGetTypeInfo(dbg_curr_process->handle, type->module, type->id, TI_GET_BASETYPE, &bt))
  680. {
  681. const WCHAR* name = NULL;
  682. switch (bt)
  683. {
  684. case btVoid: name = L"void"; break;
  685. case btChar: name = L"char"; break;
  686. case btWChar: name = L"WCHAR"; break;
  687. case btInt: name = L"int"; break;
  688. case btUInt: name = L"unsigned int"; break;
  689. case btFloat: name = L"float"; break;
  690. case btBool: name = L"bool"; break;
  691. case btLong: name = L"long int"; break;
  692. case btULong: name = L"unsigned long int"; break;
  693. case btComplex: name = L"complex"; break;
  694. default: WINE_FIXME("Unsupported basic type %u\n", bt); return FALSE;
  695. }
  696. X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(name) + 1) * sizeof(WCHAR));
  697. if (X(WCHAR*))
  698. {
  699. lstrcpyW(X(WCHAR*), name);
  700. ret = TRUE;
  701. }
  702. }
  703. return ret;
  704. }
  705. assert(type->id >= dbg_itype_first);
  706. switch (type->id)
  707. {
  708. case dbg_itype_lguint:
  709. switch (ti)
  710. {
  711. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  712. case TI_GET_LENGTH: X(DWORD64) = sizeof(dbg_lguint_t); break;
  713. case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
  714. default: WINE_FIXME("unsupported %u for lguint_t\n", ti); return FALSE;
  715. }
  716. break;
  717. case dbg_itype_lgint:
  718. switch (ti)
  719. {
  720. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  721. case TI_GET_LENGTH: X(DWORD64) = sizeof(dbg_lgint_t); break;
  722. case TI_GET_BASETYPE: X(DWORD) = btInt; break;
  723. default: WINE_FIXME("unsupported %u for lgint_t\n", ti); return FALSE;
  724. }
  725. break;
  726. case dbg_itype_unsigned_long_int:
  727. switch (ti)
  728. {
  729. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  730. case TI_GET_LENGTH: X(DWORD64) = ADDRSIZE; break;
  731. case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
  732. default: WINE_FIXME("unsupported %u for u-long int\n", ti); return FALSE;
  733. }
  734. break;
  735. case dbg_itype_signed_long_int:
  736. switch (ti)
  737. {
  738. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  739. case TI_GET_LENGTH: X(DWORD64) = ADDRSIZE; break;
  740. case TI_GET_BASETYPE: X(DWORD) = btInt; break;
  741. default: WINE_FIXME("unsupported %u for s-long int\n", ti); return FALSE;
  742. }
  743. break;
  744. case dbg_itype_unsigned_int:
  745. switch (ti)
  746. {
  747. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  748. case TI_GET_LENGTH: X(DWORD64) = 4; break;
  749. case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
  750. default: WINE_FIXME("unsupported %u for u-int\n", ti); return FALSE;
  751. }
  752. break;
  753. case dbg_itype_signed_int:
  754. switch (ti)
  755. {
  756. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  757. case TI_GET_LENGTH: X(DWORD64) = 4; break;
  758. case TI_GET_BASETYPE: X(DWORD) = btInt; break;
  759. default: WINE_FIXME("unsupported %u for s-int\n", ti); return FALSE;
  760. }
  761. break;
  762. case dbg_itype_unsigned_short_int:
  763. switch (ti)
  764. {
  765. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  766. case TI_GET_LENGTH: X(DWORD64) = 2; break;
  767. case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
  768. default: WINE_FIXME("unsupported %u for u-short int\n", ti); return FALSE;
  769. }
  770. break;
  771. case dbg_itype_signed_short_int:
  772. switch (ti)
  773. {
  774. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  775. case TI_GET_LENGTH: X(DWORD64) = 2; break;
  776. case TI_GET_BASETYPE: X(DWORD) = btInt; break;
  777. default: WINE_FIXME("unsupported %u for s-short int\n", ti); return FALSE;
  778. }
  779. break;
  780. case dbg_itype_unsigned_char_int:
  781. switch (ti)
  782. {
  783. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  784. case TI_GET_LENGTH: X(DWORD64) = 1; break;
  785. case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
  786. default: WINE_FIXME("unsupported %u for u-char int\n", ti); return FALSE;
  787. }
  788. break;
  789. case dbg_itype_signed_char_int:
  790. switch (ti)
  791. {
  792. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  793. case TI_GET_LENGTH: X(DWORD64) = 1; break;
  794. case TI_GET_BASETYPE: X(DWORD) = btInt; break;
  795. default: WINE_FIXME("unsupported %u for s-char int\n", ti); return FALSE;
  796. }
  797. break;
  798. case dbg_itype_char:
  799. switch (ti)
  800. {
  801. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  802. case TI_GET_LENGTH: X(DWORD64) = 1; break;
  803. case TI_GET_BASETYPE: X(DWORD) = btChar; break;
  804. default: WINE_FIXME("unsupported %u for char int\n", ti); return FALSE;
  805. }
  806. break;
  807. case dbg_itype_astring:
  808. switch (ti)
  809. {
  810. case TI_GET_SYMTAG: X(DWORD) = SymTagPointerType; break;
  811. case TI_GET_LENGTH: X(DWORD64) = ADDRSIZE; break;
  812. case TI_GET_TYPE: X(DWORD) = dbg_itype_char; break;
  813. default: WINE_FIXME("unsupported %u for a string\n", ti); return FALSE;
  814. }
  815. break;
  816. case dbg_itype_segptr:
  817. switch (ti)
  818. {
  819. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  820. case TI_GET_LENGTH: X(DWORD64) = 4; break;
  821. case TI_GET_BASETYPE: X(DWORD) = btInt; break;
  822. default: WINE_FIXME("unsupported %u for seg-ptr\n", ti); return FALSE;
  823. }
  824. break;
  825. case dbg_itype_short_real:
  826. switch (ti)
  827. {
  828. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  829. case TI_GET_LENGTH: X(DWORD64) = 4; break;
  830. case TI_GET_BASETYPE: X(DWORD) = btFloat; break;
  831. default: WINE_FIXME("unsupported %u for short real\n", ti); return FALSE;
  832. }
  833. break;
  834. case dbg_itype_real:
  835. switch (ti)
  836. {
  837. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  838. case TI_GET_LENGTH: X(DWORD64) = 8; break;
  839. case TI_GET_BASETYPE: X(DWORD) = btFloat; break;
  840. default: WINE_FIXME("unsupported %u for real\n", ti); return FALSE;
  841. }
  842. break;
  843. case dbg_itype_long_real:
  844. switch (ti)
  845. {
  846. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  847. case TI_GET_LENGTH: X(DWORD64) = 10; break;
  848. case TI_GET_BASETYPE: X(DWORD) = btFloat; break;
  849. default: WINE_FIXME("unsupported %u for long real\n", ti); return FALSE;
  850. }
  851. break;
  852. case dbg_itype_m128a:
  853. switch (ti)
  854. {
  855. case TI_GET_SYMTAG: X(DWORD) = SymTagBaseType; break;
  856. case TI_GET_LENGTH: X(DWORD64) = 16; break;
  857. case TI_GET_BASETYPE: X(DWORD) = btUInt; break;
  858. default: WINE_FIXME("unsupported %u for XMM register\n", ti); return FALSE;
  859. }
  860. break;
  861. default: WINE_FIXME("unsupported type id 0x%x\n", type->id);
  862. }
  863. #undef X
  864. return TRUE;
  865. }
  866. static BOOL types_compare_name(struct dbg_type type1, struct dbg_type type2, BOOL* equal)
  867. {
  868. LPWSTR name1, name2;
  869. BOOL ret;
  870. if (types_get_info(&type1, TI_GET_SYMNAME, &name1))
  871. {
  872. if (types_get_info(&type2, TI_GET_SYMNAME, &name2))
  873. {
  874. *equal = !wcscmp(name1, name2);
  875. ret = TRUE;
  876. HeapFree(GetProcessHeap(), 0, name2);
  877. }
  878. else ret = FALSE;
  879. HeapFree(GetProcessHeap(), 0, name1);
  880. }
  881. else ret = FALSE;
  882. return ret;
  883. }
  884. static BOOL types_compare_children(struct dbg_type type1, struct dbg_type type2, BOOL* equal, DWORD tag)
  885. {
  886. DWORD count1, count2, i;
  887. DWORD* children;
  888. BOOL ret;
  889. if (!types_get_info(&type1, TI_GET_CHILDRENCOUNT, &count1) ||
  890. !types_get_info(&type2, TI_GET_CHILDRENCOUNT, &count2)) return FALSE;
  891. if (count1 != count2) {*equal = FALSE; return TRUE;}
  892. if (!count1) return *equal = TRUE;
  893. if ((children = malloc(sizeof(*children) * 2 * count1)) == NULL) return FALSE;
  894. if (types_get_info(&type1, TI_FINDCHILDREN, &children[0]) &&
  895. types_get_info(&type2, TI_FINDCHILDREN, &children[count1]))
  896. {
  897. for (i = 0; i < count1; ++i)
  898. {
  899. type1.id = children[i];
  900. type2.id = children[count1 + i];
  901. switch (tag)
  902. {
  903. case SymTagFunctionType: ret = types_compare(type1, type2, equal); break;
  904. case SymTagUDT:
  905. /* each child is a SymTagData that describes the member */
  906. ret = types_compare_name(type1, type2, equal);
  907. if (ret && *equal)
  908. {
  909. /* compare type of member */
  910. ret = types_get_info(&type1, TI_GET_TYPE, &type1.id) &&
  911. types_get_info(&type2, TI_GET_TYPE, &type2.id);
  912. if (ret) ret = types_compare(type1, type2, equal);
  913. /* FIXME should compare bitfield info when present */
  914. }
  915. break;
  916. default: ret = FALSE; break;
  917. }
  918. if (!ret || !*equal) break;
  919. }
  920. if (i == count1) ret = *equal = TRUE;
  921. }
  922. else ret = FALSE;
  923. free(children);
  924. return ret;
  925. }
  926. BOOL types_compare(struct dbg_type type1, struct dbg_type type2, BOOL* equal)
  927. {
  928. DWORD tag1, tag2;
  929. DWORD64 size1, size2;
  930. DWORD bt1, bt2;
  931. DWORD count1, count2;
  932. BOOL ret;
  933. do
  934. {
  935. if (type1.module == type2.module && type1.id == type2.id)
  936. return *equal = TRUE;
  937. if (!types_get_real_type(&type1, &tag1) ||
  938. !types_get_real_type(&type2, &tag2)) return FALSE;
  939. if (type1.module == type2.module && type1.id == type2.id)
  940. return *equal = TRUE;
  941. if (tag1 != tag2) return !(*equal = FALSE);
  942. switch (tag1)
  943. {
  944. case SymTagBaseType:
  945. if (!types_get_info(&type1, TI_GET_BASETYPE, &bt1) ||
  946. !types_get_info(&type2, TI_GET_BASETYPE, &bt2) ||
  947. !types_get_info(&type1, TI_GET_LENGTH, &size1) ||
  948. !types_get_info(&type2, TI_GET_LENGTH, &size2))
  949. return FALSE;
  950. *equal = bt1 == bt2 && size1 == size2;
  951. return TRUE;
  952. case SymTagPointerType:
  953. /* compare sub types */
  954. break;
  955. case SymTagUDT:
  956. case SymTagEnum:
  957. ret = types_compare_name(type1, type2, equal);
  958. if (!ret || !*equal) return ret;
  959. ret = types_compare_children(type1, type2, equal, tag1);
  960. if (!ret || !*equal) return ret;
  961. if (tag1 == SymTagUDT) return TRUE;
  962. /* compare underlying type for enums */
  963. break;
  964. case SymTagArrayType:
  965. if (!types_get_info(&type1, TI_GET_LENGTH, &size1) ||
  966. !types_get_info(&type2, TI_GET_LENGTH, &size2) ||
  967. !types_get_info(&type1, TI_GET_COUNT, &count1) ||
  968. !types_get_info(&type2, TI_GET_COUNT, &count2)) return FALSE;
  969. if (size1 == size2 && count1 == count2)
  970. {
  971. struct dbg_type subtype1 = type1, subtype2 = type2;
  972. if (!types_get_info(&type1, TI_GET_ARRAYINDEXTYPEID, &subtype1.id) ||
  973. !types_get_info(&type2, TI_GET_ARRAYINDEXTYPEID, &subtype2.id)) return FALSE;
  974. if (!types_compare(subtype1, subtype2, equal)) return FALSE;
  975. if (!*equal) return TRUE;
  976. }
  977. else return !(*equal = FALSE);
  978. /* compare subtypes */
  979. break;
  980. case SymTagFunctionType:
  981. if (!types_compare_children(type1, type2, equal, tag1)) return FALSE;
  982. if (!*equal) return TRUE;
  983. /* compare return:ed type */
  984. break;
  985. case SymTagFunctionArgType:
  986. /* compare argument type */
  987. break;
  988. default:
  989. dbg_printf("Unsupported yet tag %d\n", tag1);
  990. return FALSE;
  991. }
  992. } while (types_get_info(&type1, TI_GET_TYPE, &type1.id) &&
  993. types_get_info(&type2, TI_GET_TYPE, &type2.id));
  994. return FALSE;
  995. }
  996. static BOOL is_basetype_char(DWORD bt)
  997. {
  998. return bt == btChar || bt == btWChar || bt == btChar8 || bt == btChar16 || bt == btChar32;
  999. }
  1000. static BOOL is_basetype_integer(DWORD bt)
  1001. {
  1002. return is_basetype_char(bt) || bt == btInt || bt == btUInt || bt == btLong || bt == btULong;
  1003. }
  1004. BOOL types_is_integral_type(const struct dbg_lvalue* lv)
  1005. {
  1006. struct dbg_type type = lv->type;
  1007. DWORD tag, bt;
  1008. if (lv->bitlen) return TRUE;
  1009. if (!types_get_real_type(&type, &tag) ||
  1010. !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
  1011. return is_basetype_integer(bt);
  1012. }
  1013. BOOL types_is_float_type(const struct dbg_lvalue* lv)
  1014. {
  1015. struct dbg_type type = lv->type;
  1016. DWORD tag, bt;
  1017. if (lv->bitlen) return FALSE;
  1018. if (!types_get_real_type(&type, &tag) ||
  1019. !types_get_info(&type, TI_GET_BASETYPE, &bt)) return FALSE;
  1020. return bt == btFloat;
  1021. }