lib.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * Dump a COFF library (lib) file
  3. *
  4. * Copyright 2006 Dmitry Timoshkov
  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. #include "config.h"
  21. #include <stdarg.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <fcntl.h>
  25. #define NONAMELESSUNION
  26. #include "windef.h"
  27. #include "winbase.h"
  28. #include "winnt.h"
  29. #include "winedump.h"
  30. static inline USHORT ushort_bswap(USHORT s)
  31. {
  32. return (s >> 8) | (s << 8);
  33. }
  34. static inline ULONG ulong_bswap(ULONG l)
  35. {
  36. return ((ULONG)ushort_bswap((USHORT)l) << 16) | ushort_bswap((USHORT)(l >> 16));
  37. }
  38. static void dump_import_object(const IMPORT_OBJECT_HEADER *ioh)
  39. {
  40. if (ioh->Version == 0)
  41. {
  42. static const char * const obj_type[] = { "code", "data", "const" };
  43. static const char * const name_type[] = { "ordinal", "name", "no prefix", "undecorate" };
  44. const char *name;
  45. printf(" Version : %X\n", ioh->Version);
  46. printf(" Machine : %X (%s)\n", ioh->Machine, get_machine_str(ioh->Machine));
  47. printf(" TimeDateStamp: %08X %s\n", ioh->TimeDateStamp, get_time_str(ioh->TimeDateStamp));
  48. printf(" SizeOfData : %08X\n", ioh->SizeOfData);
  49. name = (const char *)ioh + sizeof(*ioh);
  50. printf(" DLL name : %s\n", name + strlen(name) + 1);
  51. printf(" Symbol name : %s\n", name);
  52. printf(" Type : %s\n", (ioh->Type < ARRAY_SIZE(obj_type)) ? obj_type[ioh->Type] : "unknown");
  53. printf(" Name type : %s\n", (ioh->NameType < ARRAY_SIZE(name_type)) ? name_type[ioh->NameType] : "unknown");
  54. printf(" %-13s: %u\n", (ioh->NameType == IMPORT_OBJECT_ORDINAL) ? "Ordinal" : "Hint", ioh->u.Ordinal);
  55. printf("\n");
  56. }
  57. }
  58. static void dump_long_import(const void *base, const IMAGE_SECTION_HEADER *ish, unsigned num_sect)
  59. {
  60. unsigned i;
  61. const DWORD *imp_data5 = NULL;
  62. const WORD *imp_data6 = NULL;
  63. if (globals.do_dumpheader)
  64. printf("Section Table\n");
  65. for (i = 0; i < num_sect; i++)
  66. {
  67. if (globals.do_dumpheader)
  68. dump_section(&ish[i], NULL);
  69. if (globals.do_dump_rawdata)
  70. {
  71. dump_data((const unsigned char *)base + ish[i].PointerToRawData, ish[i].SizeOfRawData, " " );
  72. printf("\n");
  73. }
  74. if (!strcmp((const char *)ish[i].Name, ".idata$5"))
  75. {
  76. imp_data5 = (const DWORD *)((const char *)base + ish[i].PointerToRawData);
  77. }
  78. else if (!strcmp((const char *)ish[i].Name, ".idata$6"))
  79. {
  80. imp_data6 = (const WORD *)((const char *)base + ish[i].PointerToRawData);
  81. }
  82. else if (globals.do_debug && !strcmp((const char *)ish[i].Name, ".debug$S"))
  83. {
  84. const char *imp_debugS = (const char *)base + ish[i].PointerToRawData;
  85. codeview_dump_symbols(imp_debugS, 0, ish[i].SizeOfRawData);
  86. printf("\n");
  87. }
  88. }
  89. if (imp_data5)
  90. {
  91. WORD ordinal = 0;
  92. const char *name = NULL;
  93. if (imp_data5[0] & 0x80000000)
  94. ordinal = (WORD)(imp_data5[0] & ~0x80000000);
  95. if (imp_data6)
  96. {
  97. if (!ordinal) ordinal = imp_data6[0];
  98. name = (const char *)(imp_data6 + 1);
  99. }
  100. else
  101. {
  102. /* FIXME: find out a name in the section's data */
  103. }
  104. if (ordinal)
  105. {
  106. printf(" Symbol name : %s\n", name ? name : "(ordinal import) /* FIXME */");
  107. printf(" %-13s: %u\n", (imp_data5[0] & 0x80000000) ? "Ordinal" : "Hint", ordinal);
  108. printf("\n");
  109. }
  110. }
  111. }
  112. enum FileSig get_kind_lib(void)
  113. {
  114. const char* arch = PRD(0, IMAGE_ARCHIVE_START_SIZE);
  115. if (arch && !strncmp(arch, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
  116. return SIG_COFFLIB;
  117. return SIG_UNKNOWN;
  118. }
  119. void lib_dump(void)
  120. {
  121. BOOL first_linker_member = TRUE;
  122. unsigned long cur_file_pos, long_names_size = 0;
  123. const IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
  124. const char *long_names = NULL;
  125. cur_file_pos = IMAGE_ARCHIVE_START_SIZE;
  126. for (;;)
  127. {
  128. const IMPORT_OBJECT_HEADER *ioh;
  129. unsigned long size;
  130. if (!(iamh = PRD(cur_file_pos, sizeof(*iamh)))) break;
  131. if (globals.do_dumpheader)
  132. {
  133. printf("Archive member name at %08lx\n", Offset(iamh));
  134. printf("Name %.16s", iamh->Name);
  135. if (!strncmp((const char *)iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
  136. {
  137. printf(" - %s archive linker member\n", first_linker_member ? "1st" : "2nd");
  138. }
  139. else
  140. {
  141. if (long_names && iamh->Name[0] == '/')
  142. {
  143. unsigned long long_names_offset = atol((const char *)&iamh->Name[1]);
  144. if (long_names_offset < long_names_size)
  145. printf("%s\n", long_names + long_names_offset);
  146. }
  147. printf("\n");
  148. }
  149. printf("Date %.12s %s\n", iamh->Date, get_time_str(strtoul((const char *)iamh->Date, NULL, 10)));
  150. printf("UserID %.6s\n", iamh->UserID);
  151. printf("GroupID %.6s\n", iamh->GroupID);
  152. printf("Mode %.8s\n", iamh->Mode);
  153. printf("Size %.10s\n\n", iamh->Size);
  154. }
  155. cur_file_pos += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
  156. size = strtoul((const char *)iamh->Size, NULL, 10);
  157. size = (size + 1) & ~1; /* align to an even address */
  158. if (!(ioh = PRD(cur_file_pos, sizeof(*ioh)))) break;
  159. if (ioh->Sig1 == IMAGE_FILE_MACHINE_UNKNOWN && ioh->Sig2 == IMPORT_OBJECT_HDR_SIG2)
  160. {
  161. dump_import_object(ioh);
  162. }
  163. else if (!strncmp((const char *)iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
  164. {
  165. const DWORD *offset = (const DWORD *)ioh;
  166. const char *name;
  167. DWORD i, count;
  168. if (first_linker_member) /* 1st archive linker member, BE format */
  169. {
  170. count = ulong_bswap(*offset++);
  171. name = (const char *)(offset + count);
  172. printf("%u public symbols\n", count);
  173. for (i = 0; i < count; i++)
  174. {
  175. printf("%8x %s\n", ulong_bswap(offset[i]), name);
  176. name += strlen(name) + 1;
  177. }
  178. printf("\n");
  179. }
  180. else /* 2nd archive linker member, LE format */
  181. {
  182. const WORD *idx;
  183. count = *offset++;
  184. printf("%u offsets\n", count);
  185. for (i = 0; i < count; i++)
  186. {
  187. printf("%8x %8x\n", i, offset[i]);
  188. }
  189. printf("\n");
  190. offset += count;
  191. count = *offset++;
  192. idx = (const WORD *)offset;
  193. name = (const char *)(idx + count);
  194. printf("%u public symbols\n", count);
  195. for (i = 0; i < count; i++)
  196. {
  197. printf("%8x %s\n", idx[i], name);
  198. name += strlen(name) + 1;
  199. }
  200. printf("\n");
  201. }
  202. }
  203. else if (!strncmp((const char *)iamh->Name, IMAGE_ARCHIVE_LONGNAMES_MEMBER, sizeof(iamh->Name)))
  204. {
  205. long_names = PRD(cur_file_pos, size);
  206. long_names_size = size;
  207. }
  208. else
  209. {
  210. unsigned long expected_size;
  211. const IMAGE_FILE_HEADER *fh = (const IMAGE_FILE_HEADER *)ioh;
  212. if (globals.do_dumpheader)
  213. {
  214. dump_file_header(fh);
  215. if (fh->SizeOfOptionalHeader)
  216. {
  217. const IMAGE_OPTIONAL_HEADER32 *oh = (const IMAGE_OPTIONAL_HEADER32 *)((const char *)fh + sizeof(*fh));
  218. dump_optional_header(oh, fh->SizeOfOptionalHeader);
  219. }
  220. }
  221. /* Sanity check */
  222. expected_size = sizeof(*fh) + fh->SizeOfOptionalHeader + fh->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
  223. if (size > expected_size)
  224. dump_long_import(fh, (const IMAGE_SECTION_HEADER *)((const char *)fh + sizeof(*fh) + fh->SizeOfOptionalHeader), fh->NumberOfSections);
  225. }
  226. first_linker_member = FALSE;
  227. cur_file_pos += size;
  228. }
  229. }