This manifest will hold target (compiler, cpu, 32/64 exec...) related information
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/tests/dbghelp.c | 34 +++++++++++++++++++++++++++ dlls/dbghelp/tests/debuggee.h | 7 +++++ dlls/dbghelp/tests/debuggee1.c | 51 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+)
diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index 123989442bf..4e8907ac26b 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -21,6 +21,9 @@ #include "dbghelp.h" #include "wine/test.h"
+#define DEBUGGEE_NODEFINE +#include "debuggee.h" + struct debuggee { const char* name; /* name of main module */ @@ -29,6 +32,12 @@ struct debuggee HANDLE hThread; /* either new thread calling stack_walk_thread, or main thread */ DWORD64 base; DWORD64 size; + unsigned char* manifest; + /* 0 : version (1) + 1 : sizeof foobar + 2 : for each field of foobar (ch, array, bf1, bf2, fb3, u), 3 values + 20 | offset, size, bit position (255 if not a bitfield) + */ };
#if defined(__i386__) || defined(__x86_64__) @@ -167,6 +176,9 @@ static BOOL start_process(struct debuggee* dbg, const char* other) { DWORD count; BOOL ret; + char si_buf[sizeof(SYMBOL_INFO) + 200]; + SYMBOL_INFO *si = (SYMBOL_INFO *)si_buf; + SIZE_T nread;
memset(dbg, 0, sizeof(*dbg)); if (other) @@ -226,6 +238,27 @@ static BOOL start_process(struct debuggee* dbg, const char* other) { /* force the main module */ find_main_module_cb(dbg->name, (DWORD_PTR)&start_process, dbg); + ok(build_manifest(), "Couldn't build debuggee manifest\n"); + } + + si->SizeOfStruct = sizeof(*si); + si->MaxNameLen = 200; + ret = SymFromName(dbg->hProcess, "debuggee_manifest", si); + + if (!ret) + { + skip("Couldn't get debug information out of %s: %u\n", dbg->name, GetLastError()); + return FALSE; + } + if ((dbg->manifest = HeapAlloc(GetProcessHeap(), 0, si->Size)) == NULL || + si->Size != DEBUGGEE_MANIFEST_SIZE || + !ReadProcessMemory(dbg->hProcess, (void*)(DWORD_PTR)si->Address, dbg->manifest, si->Size, &nread) || + nread != si->Size || + dbg->manifest[0] != DEBUGGEE_MANIFEST_VERSION) + { + skip("Couldn't access the debuggee manifest %u\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, dbg->manifest); + return FALSE; }
return TRUE; @@ -244,6 +277,7 @@ static void close_process(const struct debuggee* dbg) CloseHandle(dbg->hProcess); CloseHandle(dbg->hThread); } + HeapFree(GetProcessHeap(), 0, dbg->manifest); }
START_TEST(dbghelp) diff --git a/dlls/dbghelp/tests/debuggee.h b/dlls/dbghelp/tests/debuggee.h index 9e181f1ba17..239a5085ae7 100644 --- a/dlls/dbghelp/tests/debuggee.h +++ b/dlls/dbghelp/tests/debuggee.h @@ -1,3 +1,4 @@ +#ifndef DEBUGGEE_NODEFINE /* avoid including standard headers, just to keep debug information as lean as possible */ typedef void* HANDLE; typedef unsigned long DWORD; @@ -10,6 +11,7 @@ extern DWORD __stdcall SuspendThread(HANDLE h); #define UNREFERENCED_PARAMETER(u) (void)(u)
/* end of standard definitions */ +#endif
#if defined(__GNUC__) #define NOINLINE __attribute__((noinline)) @@ -21,3 +23,8 @@ extern DWORD __stdcall SuspendThread(HANDLE h);
extern DWORD trucmuche(DWORD*); extern DWORD stack_walk_bottom(void); + +#define DEBUGGEE_MANIFEST_VERSION 1 +#define DEBUGGEE_MANIFEST_SIZE 20 + +extern DWORD build_manifest(void); diff --git a/dlls/dbghelp/tests/debuggee1.c b/dlls/dbghelp/tests/debuggee1.c index e73f36759e2..8a8f613eddb 100644 --- a/dlls/dbghelp/tests/debuggee1.c +++ b/dlls/dbghelp/tests/debuggee1.c @@ -54,11 +54,62 @@ scaramouche: return ((other * base) & (1UL << 18)) != 0; }
+unsigned char debuggee_manifest[DEBUGGEE_MANIFEST_SIZE]; + +#define FIELD_OFFSET(s,f) ((unsigned char)((char*)(&((struct s*)0)->f)-(char*)0)) + +DWORD build_manifest(void) +{ + unsigned i = 0; + + myfoobar.bf1 = 1; + myfoobar.bf2 = 1; + myfoobar.bf3 = 1; + + if (FIELD_OFFSET(foobar, array) + sizeof(myfoobar.array) + sizeof(unsigned) == FIELD_OFFSET(foobar, u) && + ((unsigned*)&myfoobar)[(FIELD_OFFSET(foobar, array) + sizeof(myfoobar.array)) / sizeof(unsigned)] == 0x409u) + { + debuggee_manifest[i++] = DEBUGGEE_MANIFEST_VERSION; + debuggee_manifest[i++] = sizeof(myfoobar); + + debuggee_manifest[i++] = FIELD_OFFSET(foobar, ch); + debuggee_manifest[i++] = sizeof(myfoobar.ch); + debuggee_manifest[i++] = 255u; + + debuggee_manifest[i++] = FIELD_OFFSET(foobar, array); + debuggee_manifest[i++] = sizeof(myfoobar.array); + debuggee_manifest[i++] = 255u; + + debuggee_manifest[i++] = FIELD_OFFSET(foobar, array) + sizeof(myfoobar.array); + debuggee_manifest[i++] = sizeof(unsigned); + debuggee_manifest[i++] = 0; + + debuggee_manifest[i++] = FIELD_OFFSET(foobar, array) + sizeof(myfoobar.array); + debuggee_manifest[i++] = sizeof(unsigned); + debuggee_manifest[i++] = 3; + + debuggee_manifest[i++] = FIELD_OFFSET(foobar, array) + sizeof(myfoobar.array); + debuggee_manifest[i++] = sizeof(unsigned); + debuggee_manifest[i++] = 10; + + debuggee_manifest[i++] = FIELD_OFFSET(foobar, u); + debuggee_manifest[i++] = sizeof(myfoobar.u); + debuggee_manifest[i++] = 255u; + + if (i != sizeof(debuggee_manifest)) + debuggee_manifest[0] = 0; + } + else /* unsupported alignment or bitfield disposition */ + debuggee_manifest[0] = 0; + return debuggee_manifest[0]; +} + int __stdcall WinMain(void* hInstance, void* hPrevInstance, char* lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine);
+ build_manifest(); return function_AA(&myfoobar, nCmdShow ? 0 : 123) + stack_walk_bottom(); }