winedump: Add partial COFF library support to the winedump. Take 2
Dmitry Timoshkov
dmitry at codeweavers.com
Tue Nov 28 04:40:13 CST 2006
Hello,
here is a resend of the previous patch, which adds the libraries to
the list of auto-detected binaries.
---
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 partial COFF library support to the winedump.
---
tools/winedump/Makefile.in | 1
tools/winedump/dump.c | 30 ++++++----
tools/winedump/lib.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
tools/winedump/main.c | 4 +
tools/winedump/pe.c | 2 -
tools/winedump/winedump.h | 5 +-
6 files changed, 164 insertions(+), 14 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/dump.c b/tools/winedump/dump.c
index fe86190..9670a98 100644
--- a/tools/winedump/dump.c
+++ b/tools/winedump/dump.c
@@ -163,6 +163,7 @@ static void do_dump( enum FileSig sig, c
static enum FileSig check_headers(void)
{
+ const char *p;
const WORD* pw;
const DWORD* pdw;
const IMAGE_DOS_HEADER* dh;
@@ -204,23 +205,27 @@ static enum FileSig check_headers(void)
printf("Can't get the extented signature, aborting\n");
}
}
- break;
+ return sig;
+
case 0x4944: /* "DI" */
- sig = SIG_DBG;
- break;
+ return SIG_DBG;
+
case 0x444D: /* "MD" */
pdw = PRD(0, sizeof(DWORD));
if (pdw && *pdw == 0x504D444D) /* "MDMP" */
- sig = SIG_MDMP;
- else
- sig = SIG_UNKNOWN;
- break;
+ return SIG_MDMP;
+ return SIG_UNKNOWN;
+
default:
- printf("No known main signature (%.2s/%x), aborting\n", (const char *)pw, *pw);
- sig = SIG_UNKNOWN;
+ break;
}
- return sig;
+ p = PRD(0, IMAGE_ARCHIVE_START_SIZE);
+ if (p && !strncmp(p, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
+ return SIG_COFFLIB;
+
+ printf("No known main signature (%.2s/%x), aborting\n", (const char *)pw, *pw);
+ return SIG_UNKNOWN;
}
int dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
@@ -269,6 +274,11 @@ #endif
case SIG_MDMP:
mdmp_dump();
break;
+
+ case SIG_COFFLIB:
+ printf("Contents of \"%s\": %ld bytes\n\n", name, dump_total_len);
+ lib_dump(dump_base, dump_total_len);
+ break;
}
}
else
diff --git a/tools/winedump/lib.c b/tools/winedump/lib.c
new file mode 100644
index 0000000..56242e8
--- /dev/null
+++ b/tools/winedump/lib.c
@@ -0,0 +1,136 @@
+/*
+ * 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");
+ }
+}
+
+void lib_dump(const char *lib_base, unsigned long lib_size)
+{
+ long cur_file_pos;
+ IMAGE_ARCHIVE_MEMBER_HEADER *iamh;
+
+ if (strncmp(lib_base, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
+ {
+ printf("Not a valid COFF library file");
+ return;
+ }
+
+ iamh = (IMAGE_ARCHIVE_MEMBER_HEADER *)(lib_base + IMAGE_ARCHIVE_START_SIZE);
+ cur_file_pos = IMAGE_ARCHIVE_START_SIZE;
+
+ while (cur_file_pos < lib_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));
+ }
+}
diff --git a/tools/winedump/main.c b/tools/winedump/main.c
index 36a105b..f71c49a 100644
--- a/tools/winedump/main.c
+++ b/tools/winedump/main.c
@@ -230,7 +230,7 @@ static const struct my_option option_tab
{"-S", SPEC, 1, do_symfile, "-S symfile Search only prototype names found in 'symfile'"},
{"-q", SPEC, 0, do_quiet, "-q Don't show progress (quiet)."},
{"-v", SPEC, 0, do_verbose, "-v Show lots of detail while working (verbose)."},
- {"dump", DUMP, 0, do_dump, "dump <mod> Dumps the content of the module (dll, exe...) named <mod>"},
+ {"dump", DUMP, 0, do_dump, "dump <file> Dumps the contents of the file (dll, exe, lib...)"},
{"-C", DUMP, 0, do_symdmngl, "-C Turns on symbol demangling"},
{"-f", DUMP, 0, do_dumphead, "-f Dumps file header information"},
{"-G", DUMP, 0, do_rawdebug, "-G Dumps raw debug information"},
@@ -244,7 +244,7 @@ static const struct my_option option_tab
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 <file> | emf <emf> | lnk <lnk>]\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++)
diff --git a/tools/winedump/pe.c b/tools/winedump/pe.c
index d379534..7e87ff0 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..bb7f966 100644
--- a/tools/winedump/winedump.h
+++ b/tools/winedump/winedump.h
@@ -221,8 +221,10 @@ 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};
+enum FileSig {SIG_UNKNOWN, SIG_DOS, SIG_PE, SIG_DBG, SIG_NE, SIG_LE, SIG_MDMP, SIG_COFFLIB};
const void* PRD(unsigned long prd, unsigned long len);
unsigned long Offset(const void* ptr);
@@ -238,6 +240,7 @@ void dump_unicode_str( const
void ne_dump( const void *exe, size_t exe_size );
void le_dump( const void *exe, size_t exe_size );
void mdmp_dump( void );
+void lib_dump( const char *lib_base, unsigned long lib_size );
void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr, unsigned szstr);
--
1.4.2
More information about the wine-patches
mailing list