include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / tools / winedump / lib.c
blob0b94adb9b332afba31244658c684f9911bc41848
1 /*
2 * Dump a COFF library (lib) file
4 * Copyright 2006 Dmitry Timoshkov
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.
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.
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
21 #include "config.h"
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <fcntl.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnt.h"
32 #include "winedump.h"
34 static inline USHORT ushort_bswap(USHORT s)
36 return (s >> 8) | (s << 8);
39 static inline UINT ulong_bswap(UINT l)
41 return ((UINT)ushort_bswap((USHORT)l) << 16) | ushort_bswap(l >> 16);
44 static void dump_import_object(const IMPORT_OBJECT_HEADER *ioh)
46 if (ioh->Version == 0)
48 static const char * const obj_type[] = { "code", "data", "const" };
49 static const char * const name_type[] = { "ordinal", "name", "no prefix", "undecorate", "export as" };
50 const char *name, *dll_name;
52 printf(" Version : %X\n", ioh->Version);
53 printf(" Machine : %X (%s)\n", ioh->Machine, get_machine_str(ioh->Machine));
54 printf(" TimeDateStamp: %08X %s\n", (UINT)ioh->TimeDateStamp, get_time_str(ioh->TimeDateStamp));
55 printf(" SizeOfData : %08X\n", (UINT)ioh->SizeOfData);
56 name = (const char *)ioh + sizeof(*ioh);
57 dll_name = name + strlen(name) + 1;
58 printf(" DLL name : %s\n", dll_name);
59 printf(" Symbol name : %s\n", name);
60 printf(" Type : %s\n", (ioh->Type < ARRAY_SIZE(obj_type)) ? obj_type[ioh->Type] : "unknown");
61 printf(" Name type : %s\n", (ioh->NameType < ARRAY_SIZE(name_type)) ? name_type[ioh->NameType] : "unknown");
62 if (ioh->NameType == IMPORT_OBJECT_NAME_EXPORTAS)
63 printf(" Export name : %s\n", dll_name + strlen(dll_name) + 1);
64 printf(" %-13s: %u\n", (ioh->NameType == IMPORT_OBJECT_ORDINAL) ? "Ordinal" : "Hint", ioh->Ordinal);
65 printf("\n");
69 static void dump_long_import(const void *base, const IMAGE_SECTION_HEADER *ish, unsigned num_sect)
71 unsigned i;
72 const DWORD *imp_data5 = NULL;
73 const WORD *imp_data6 = NULL;
75 if (globals.do_dumpheader)
76 printf("Section Table\n");
78 for (i = 0; i < num_sect; i++)
80 if (globals.do_dumpheader)
81 dump_section(&ish[i], NULL);
83 if (globals.do_dump_rawdata)
85 dump_data((const unsigned char *)base + ish[i].PointerToRawData, ish[i].SizeOfRawData, " " );
86 printf("\n");
89 if (!strcmp((const char *)ish[i].Name, ".idata$5"))
91 imp_data5 = (const DWORD *)((const char *)base + ish[i].PointerToRawData);
93 else if (!strcmp((const char *)ish[i].Name, ".idata$6"))
95 imp_data6 = (const WORD *)((const char *)base + ish[i].PointerToRawData);
97 else if (globals.do_debug && !strcmp((const char *)ish[i].Name, ".debug$S"))
99 const char *imp_debugS = (const char *)base + ish[i].PointerToRawData;
101 codeview_dump_symbols(imp_debugS, 0, ish[i].SizeOfRawData);
102 printf("\n");
106 if (imp_data5)
108 WORD ordinal = 0;
109 const char *name = NULL;
111 if (imp_data5[0] & 0x80000000)
112 ordinal = (WORD)(imp_data5[0] & ~0x80000000);
114 if (imp_data6)
116 if (!ordinal) ordinal = imp_data6[0];
117 name = (const char *)(imp_data6 + 1);
119 else
121 /* FIXME: find out a name in the section's data */
124 if (ordinal)
126 printf(" Symbol name : %s\n", name ? name : "(ordinal import) /* FIXME */");
127 printf(" %-13s: %u\n", (imp_data5[0] & 0x80000000) ? "Ordinal" : "Hint", ordinal);
128 printf("\n");
133 enum FileSig get_kind_lib(void)
135 const char* arch = PRD(0, IMAGE_ARCHIVE_START_SIZE);
136 if (arch && !strncmp(arch, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
137 return SIG_COFFLIB;
138 return SIG_UNKNOWN;
141 void lib_dump(void)
143 BOOL first_linker_member = TRUE;
144 unsigned long cur_file_pos, long_names_size = 0;
145 const IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
146 const char *long_names = NULL;
148 cur_file_pos = IMAGE_ARCHIVE_START_SIZE;
150 for (;;)
152 const IMPORT_OBJECT_HEADER *ioh;
153 unsigned long size;
155 if (!(iamh = PRD(cur_file_pos, sizeof(*iamh)))) break;
157 if (globals.do_dumpheader)
159 printf("Archive member name at %08lx\n", Offset(iamh));
161 printf("Name %.16s", iamh->Name);
162 if (!strncmp((const char *)iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
164 printf(" - %s archive linker member\n", first_linker_member ? "1st" : "2nd");
166 else
168 if (long_names && iamh->Name[0] == '/')
170 unsigned long long_names_offset = atol((const char *)&iamh->Name[1]);
171 if (long_names_offset < long_names_size)
172 printf("%s\n", long_names + long_names_offset);
174 printf("\n");
176 printf("Date %.12s %s\n", iamh->Date, get_time_str(strtoul((const char *)iamh->Date, NULL, 10)));
177 printf("UserID %.6s\n", iamh->UserID);
178 printf("GroupID %.6s\n", iamh->GroupID);
179 printf("Mode %.8s\n", iamh->Mode);
180 printf("Size %.10s\n\n", iamh->Size);
183 cur_file_pos += sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
185 size = strtoul((const char *)iamh->Size, NULL, 10);
186 size = (size + 1) & ~1; /* align to an even address */
188 if (!(ioh = PRD(cur_file_pos, sizeof(*ioh)))) break;
190 if (ioh->Sig1 == IMAGE_FILE_MACHINE_UNKNOWN && ioh->Sig2 == IMPORT_OBJECT_HDR_SIG2)
192 dump_import_object(ioh);
194 else if (!strncmp((const char *)iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
196 const UINT *offset = (const UINT *)ioh;
197 const char *name;
198 UINT i, count;
200 if (first_linker_member) /* 1st archive linker member, BE format */
202 count = ulong_bswap(*offset++);
203 name = (const char *)(offset + count);
204 printf("%u public symbols\n", count);
205 for (i = 0; i < count; i++)
207 printf("%8x %s\n", ulong_bswap(offset[i]), name);
208 name += strlen(name) + 1;
210 printf("\n");
212 else /* 2nd archive linker member, LE format */
214 const WORD *idx;
216 count = *offset++;
217 printf("%u offsets\n", count);
218 for (i = 0; i < count; i++)
220 printf("%8x %8x\n", i, offset[i]);
222 printf("\n");
224 offset += count;
225 count = *offset++;
226 idx = (const WORD *)offset;
227 name = (const char *)(idx + count);
228 printf("%u public symbols\n", count);
229 for (i = 0; i < count; i++)
231 printf("%8x %s\n", idx[i], name);
232 name += strlen(name) + 1;
234 printf("\n");
237 else if (!strncmp((const char *)iamh->Name, "/<ECSYMBOLS>/ ", sizeof(iamh->Name)))
239 unsigned int i, *count = (unsigned int *)ioh;
240 unsigned short *offsets = (unsigned short *)(count + 1);
241 const char *name = (const char *)(offsets + *count);
243 printf("%u EC symbols\n", *count);
244 for (i = 0; i < *count; i++)
246 printf("%8x %s\n", offsets[i], name);
247 name += strlen(name) + 1;
249 printf("\n");
251 else if (!strncmp((const char *)iamh->Name, IMAGE_ARCHIVE_LONGNAMES_MEMBER, sizeof(iamh->Name)))
253 long_names = PRD(cur_file_pos, size);
254 long_names_size = size;
256 else
258 unsigned long expected_size;
259 const IMAGE_FILE_HEADER *fh = (const IMAGE_FILE_HEADER *)ioh;
261 if (globals.do_dumpheader)
263 dump_file_header(fh, FALSE);
264 if (fh->SizeOfOptionalHeader)
266 const IMAGE_OPTIONAL_HEADER32 *oh = (const IMAGE_OPTIONAL_HEADER32 *)((const char *)fh + sizeof(*fh));
267 dump_optional_header(oh);
270 /* Sanity check */
271 expected_size = sizeof(*fh) + fh->SizeOfOptionalHeader + fh->NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
272 if (size > expected_size)
273 dump_long_import(fh, (const IMAGE_SECTION_HEADER *)((const char *)fh + sizeof(*fh) + fh->SizeOfOptionalHeader), fh->NumberOfSections);
276 first_linker_member = FALSE;
277 cur_file_pos += size;