[6/6] Add a partial COFF library support to the winedump
Dmitry Timoshkov
dmitry at codeweavers.com
Sun Nov 26 02:06:46 CST 2006
Hello,
this implementation is able to parse imports libraries from the PSDK
and hopefully should help interested parties to check/synchronize ordinal
imports between Wine and Windows.
The dumper is not able (yet) to parse import libraries with the long format
described in Portable Executable and Common Object File Format Specification
and uuid.lib.
Here is a sample output of the dumper (emulating what dumpbin emits):
Contents of "ComCtl32.Lib": 26302 bytes
Version : 0
Machine : 14C (i386)
TimeDateStamp: 40760E7E Fri Apr 9 11:46:22 2004
SizeOfData : 00000055
DLL name : COMCTL32.dll
Symbol name : ?CreateToolbar@@YGPAUHWND__@@PAU1 at KIHPAUHINSTANCE__@@IPBU_TBBUTTON@@H at Z
Type : code
Name type : ordinal
Ordinal : 7
Version : 0
Machine : 14C (i386)
TimeDateStamp: 40760E7E Fri Apr 9 11:46:22 2004
SizeOfData : 0000001E
DLL name : COMCTL32.dll
Symbol name : _AddMRUStringW at 8
Type : code
Name type : ordinal
Ordinal : 401
Version : 0
Machine : 14C (i386)
TimeDateStamp: 40760E7E Fri Apr 9 11:46:22 2004
SizeOfData : 0000001F
DLL name : COMCTL32.dll
Symbol name : _CreateMRUListW at 4
Type : code
Name type : ordinal
Ordinal : 400
Version : 0
Machine : 14C (i386)
TimeDateStamp: 40760E7E Fri Apr 9 11:46:22 2004
SizeOfData : 00000024
DLL name : COMCTL32.dll
Symbol name : _CreateMappedBitmap at 20
Type : code
Name type : ordinal
Ordinal : 8
Version : 0
Machine : 14C (i386)
TimeDateStamp: 40760E7E Fri Apr 9 11:46:22 2004
SizeOfData : 00000028
DLL name : COMCTL32.dll
Symbol name : _CreatePropertySheetPage at 4
Type : code
Name type : undecorate
Hint : 3
Changelog:
winedump: Add a partial COFF library support to the winedump.
---
tools/winedump/Makefile.in | 1
tools/winedump/lib.c | 164 ++++++++++++++++++++++++++++++++++++++++++++
tools/winedump/main.c | 19 +++++
tools/winedump/pe.c | 2 -
tools/winedump/winedump.h | 7 ++
5 files changed, 190 insertions(+), 3 deletions(-)
diff --git a/tools/winedump/Makefile.in b/tools/winedump/Makefile.in
index 909a135..a670ceb 100644
--- a/tools/winedump/Makefile.in
+++ b/tools/winedump/Makefile.in
@@ -13,6 +13,7 @@ C_SRCS = \
dump.c \
emf.c \
le.c \
+ lib.c \
lnk.c \
main.c \
minidump.c \
diff --git a/tools/winedump/lib.c b/tools/winedump/lib.c
new file mode 100644
index 0000000..e6638a0
--- /dev/null
+++ b/tools/winedump/lib.c
@@ -0,0 +1,164 @@
+/*
+ * Dump a COFF library (lib) file
+ *
+ * Copyright 2006 Dmitry Timoshkov
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* FIXME: Add support for import library with the long format described in
+ * Microsoft Portable Executable and Common Object File Format Specification.
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <fcntl.h>
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "winnt.h"
+
+#include "winedump.h"
+
+static void dump_import_object(const IMPORT_OBJECT_HEADER *ioh)
+{
+ if (ioh->Version >= 1)
+ {
+#if 0 /* FIXME: supposed to handle uuid.lib but it doesn't */
+ const ANON_OBJECT_HEADER *aoh = (const ANON_OBJECT_HEADER *)ioh;
+
+ printf("CLSID {%08x-%04x-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ aoh->ClassID.Data1, aoh->ClassID.Data2, aoh->ClassID.Data3,
+ aoh->ClassID.Data4[0], aoh->ClassID.Data4[1], aoh->ClassID.Data4[2], aoh->ClassID.Data4[3],
+ aoh->ClassID.Data4[4], aoh->ClassID.Data4[5], aoh->ClassID.Data4[6], aoh->ClassID.Data4[7]);
+#endif
+ }
+ else
+ {
+ static const char * const obj_type[] = { "code", "data", "const" };
+ static const char * const name_type[] = { "ordinal", "name", "no prefix", "undecorate" };
+ const char *name;
+
+ printf(" Version : %X\n", ioh->Version);
+ printf(" Machine : %X (%s)\n", ioh->Machine, get_machine_str(ioh->Machine));
+ printf(" TimeDateStamp: %08X %s\n", ioh->TimeDateStamp, get_time_str(ioh->TimeDateStamp));
+ printf(" SizeOfData : %08X\n", ioh->SizeOfData);
+ name = (const char *)ioh + sizeof(*ioh);
+ printf(" DLL name : %s\n", name + strlen(name) + 1);
+ printf(" Symbol name : %s\n", name);
+ printf(" Type : %s\n", (ioh->Type < sizeof(obj_type)/sizeof(obj_type[0])) ? obj_type[ioh->Type] : "unknown");
+ printf(" Name type : %s\n", (ioh->NameType < sizeof(name_type)/sizeof(name_type[0])) ? name_type[ioh->NameType] : "unknown");
+ printf(" %-13s: %u\n", (ioh->NameType == IMPORT_OBJECT_ORDINAL) ? "Ordinal" : "Hint", ioh->u.Ordinal);
+ printf("\n");
+ }
+}
+
+int dump_lib(const char *lib_name)
+{
+ int fd;
+ struct stat st;
+ long cur_file_pos;
+ char *lib_base;
+ IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
+
+ fd = open(lib_name, O_RDONLY | O_BINARY);
+ if (fd == -1) fatal("Can't open input file");
+
+ if (fstat(fd, &st) < 0) fatal("Can't get input file size");
+ if (st.st_size <= IMAGE_ARCHIVE_START_SIZE) fatal("Not a valid COFF library file");
+
+#ifdef HAVE_MMAP
+ if ((lib_base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == (void *)-1)
+#endif
+ {
+ if (!(lib_base = malloc(st.st_size)))
+ fatal("Out of memory");
+ if (read(fd, lib_base, st.st_size) != st.st_size)
+ fatal("Cannot read input file");
+ }
+
+ if (strncmp(lib_base, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
+ fatal("Not a valid COFF library file");
+
+ printf(" Contents of \"%s\": %lu bytes\n\n", lib_name, (long)st.st_size);
+
+ iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)(lib_base + IMAGE_ARCHIVE_START_SIZE);
+ cur_file_pos = IMAGE_ARCHIVE_START_SIZE;
+
+ while (cur_file_pos < st.st_size)
+ {
+ IMPORT_OBJECT_HEADER *ioh;
+ long size;
+
+#if 0 /* left here for debugging purposes, also should be helpful for
+ * adding support for new library formats.
+ */
+ printf("cur_file_pos %08lx\n", (ULONG_PTR)iamh - (ULONG_PTR)lib_base);
+
+ printf("Name %.16s", iamh->Name);
+ if (!strncmp(iamh->Name, IMAGE_ARCHIVE_LINKER_MEMBER, sizeof(iamh->Name)))
+ {
+ printf(" - %s archive linker member\n",
+ cur_file_pos == IMAGE_ARCHIVE_START_SIZE ? "1st" : "2nd");
+ }
+ else
+ printf("\n");
+ printf("Date %.12s\n", iamh->Date);
+ printf("UserID %.6s\n", iamh->UserID);
+ printf("GroupID %.6s\n", iamh->GroupID);
+ printf("Mode %.8s\n", iamh->Mode);
+ printf("Size %.10s\n", iamh->Size);
+#endif
+ /* FIXME: only import library contents with the short format are
+ * recognized.
+ */
+ ioh = (IMPORT_OBJECT_HEADER *)((char *)iamh + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
+ if (ioh->Sig1 == IMAGE_FILE_MACHINE_UNKNOWN && ioh->Sig2 == IMPORT_OBJECT_HDR_SIG2)
+ {
+ dump_import_object(ioh);
+ }
+
+ size = strtoul((const char *)iamh->Size, NULL, 10);
+ size = (size + 1) & ~1; /* align to an even address */
+
+ cur_file_pos += size + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER);
+ iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)((char *)iamh + size + sizeof(IMAGE_ARCHIVE_MEMBER_HEADER));
+ }
+
+#ifdef HAVE_MMAP
+ if (munmap(lib_base, st.st_size) == -1)
+#endif
+ {
+ free(lib_base);
+ }
+ close(fd);
+
+ return 1;
+}
diff --git a/tools/winedump/main.c b/tools/winedump/main.c
index 36a105b..0c81b69 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -94,6 +94,13 @@ static void do_dumplnk(void)
}
+static void do_dumplib(void)
+{
+ if (globals.mode != NONE) fatal("Only one mode can be specified\n");
+ globals.mode = LIB;
+}
+
+
static void do_code (void)
{
globals.do_code = 1;
@@ -238,13 +245,14 @@ static const struct my_option option_tab
{"-x", DUMP, 0, do_dumpall, "-x Dumps everything"},
{"emf", EMF, 0, do_dumpemf, "emf Dumps an Enhanced Meta File"},
{"lnk", LNK, 0, do_dumplnk, "lnk Dumps a shortcut (.lnk) file"},
+ {"lib", LIB, 0, do_dumplib, "lib Dumps a COFF library (.lib) file"},
{NULL, NONE, 0, NULL, NULL}
};
void do_usage (void)
{
const struct my_option *opt;
- printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <dll> | emf <emf> | lnk <lnk>]\n");
+ printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <dll> | emf <emf> | lnk <lnk> | lib <lib>]\n");
printf ("Mode options (can be put as the mode (sym/spec/dump...) is declared):\n");
printf ("\tWhen used in --help mode\n");
for (opt = option_table; opt->name; opt++)
@@ -270,6 +278,10 @@ void do_usage (void)
for (opt = option_table; opt->name; opt++)
if (opt->mode == LNK)
printf ("\t %s\n", opt->usage);
+ printf ("\tWhen used in lib mode\n");
+ for (opt = option_table; opt->name; opt++)
+ if (opt->mode == LIB)
+ printf ("\t %s\n", opt->usage);
puts ("");
exit (1);
@@ -511,6 +523,11 @@ #endif
fatal("No file name has been given\n");
dump_lnk(globals.input_name);
break;
+ case LIB:
+ if (globals.input_name == NULL)
+ fatal("No file name has been given\n");
+ dump_lib(globals.input_name);
+ break;
}
return 0;
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index d452525..2d31dab 100644
--- a/tools/winedump/pe.c
+++ b/tools/winedump/pe.c
@@ -48,7 +48,7 @@ #include "pe.h"
static const IMAGE_NT_HEADERS32* PE_nt_headers;
-static const char* get_machine_str(DWORD mach)
+const char *get_machine_str(int mach)
{
switch (mach)
{
diff --git a/tools/winedump/winedump.h b/tools/winedump/winedump.h
index f12b618..909119d 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -72,7 +72,7 @@ #define SYM_STDCALL 0x2
#define SYM_THISCALL 0x4
#define SYM_DATA 0x8 /* Data, not a function */
-typedef enum {NONE, DMGL, SPEC, DUMP, EMF, LNK} Mode;
+typedef enum {NONE, DMGL, SPEC, DUMP, EMF, LNK, LIB } Mode;
/* Structure holding a parsed symbol */
typedef struct __parsed_symbol
@@ -162,6 +162,9 @@ int dump_emf (const char *emf);
/* LNK functions */
int dump_lnk (const char *lnk);
+/* LIB functions */
+int dump_lib (const char *lib);
+
/* Image functions */
void dump_file(const char* name);
@@ -221,6 +224,8 @@ const char *str_find_set (const char *st
char *str_toupper (char *str);
+const char *get_machine_str(int mach);
+
/* file dumping functions */
enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE, SIG_LE, SIG_MDMP};
--
1.4.2
More information about the wine-patches
mailing list