Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
June 2018
- 68 participants
- 1149 messages
Re: [PATCH 2/7] wsdapi: Add critical section around notification sinks.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 14, 2018
Re: [PATCH 1/7] wsdapi: Add support for listening for UDP multicast broadcasts.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 14, 2018
Re: [PATCH 2/4] ntdll: Report logical cores per physical core through mask.
by Roderick Colenbrander
Please still review the series for overall. I just realized though the
code can be slightly simplified if I still submit 'core_id' to
logical_proc_info_add_by_id. The lookup code within that function
doesn't have to parse the masks (ProcessorMask or GroupMask[0]) and it
is cleaner and more future proof that way.
Thanks,
Roderick
On Wed, Jun 13, 2018 at 10:48 PM, Roderick Colenbrander
<thunderbird2k(a)gmail.com> wrote:
> Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
> ---
> dlls/ntdll/nt.c | 28 ++++++++++++++++++++++------
> 1 file changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
> index e6458b98f2..0b69f7de44 100644
> --- a/dlls/ntdll/nt.c
> +++ b/dlls/ntdll/nt.c
> @@ -1325,8 +1325,16 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
> (*pdata)[i].ProcessorMask |= mask;
> return TRUE;
> }
> - }else
> - i = *len;
> + }
> + else
> + {
> + for(i=0; i<*len; i++)
> + {
> + if ((*pdata)[i].Relationship==rel && (*pdata)[i].ProcessorMask==mask &&
> + (*pdata)[i].u.Reserved[1]==id)
> + return TRUE;
> + }
> + }
>
> while(*len == *pmax_len)
> {
> @@ -1352,6 +1360,11 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
> dataex->u.Processor.GroupMask[0].Mask |= mask;
> return TRUE;
> }
> + else if (rel == RelationProcessorCore && dataex->Relationship == rel &&
> + dataex->u.Processor.GroupMask[0].Mask == mask && dataex->u.Processor.Reserved[1] == id)
> + {
> + return TRUE;
> + }
> ofs += dataex->Size;
> }
>
> @@ -1548,6 +1561,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
>
> for(i=beg; i<=end; i++)
> {
> + ULONG_PTR thread_mask = 0;
> +
> if(i > 8*sizeof(ULONG_PTR))
> {
> FIXME("skipping logical processor %d\n", i);
> @@ -1568,15 +1583,16 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
> return STATUS_NO_MEMORY;
> }
>
> - sprintf(name, core_info, i, "core_id");
> + /* Mask of logical threads sharing same physical core. */
> + sprintf(name, core_info, i, "thread_siblings");
> f = fopen(name, "r");
> if(f)
> {
> - fscanf(f, "%u", &r);
> + fscanf(f, "%lx", &thread_mask);
> fclose(f);
> }
> - else r = i;
> - if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, (ULONG_PTR)1 << i))
> + else thread_mask = 1<<i;
> + if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, thread_mask))
> {
> fclose(fcpu_list);
> return STATUS_NO_MEMORY;
> --
> 2.14.4
>
June 14, 2018
[PATCH 4/4] ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 9d50ad1891..f866091c38 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1355,7 +1355,8 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
(*pdata)[i].Relationship = rel;
(*pdata)[i].ProcessorMask = mask;
- /* TODO: set processor core flags */
+ if (rel == RelationProcessorCore)
+ (*pdata)[i].u.ProcessorCore.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
(*pdata)[i].u.Reserved[0] = 0;
(*pdata)[i].u.Reserved[1] = id;
*len = i+1;
--
2.14.4
June 14, 2018
[PATCH 3/4] ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 27 +++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 0b69f7de44..9d50ad1891 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,17 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, DWORD *pmax_len,
LOGICAL_PROCESSOR_RELATIONSHIP rel, DWORD id, ULONG_PTR mask)
@@ -1381,7 +1392,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->Relationship = rel;
dataex->Size = log_proc_ex_size_plus(sizeof(PROCESSOR_RELATIONSHIP));
- dataex->u.Processor.Flags = 0; /* TODO */
+ if (rel == RelationProcessorCore)
+ dataex->u.Processor.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
+ else
+ dataex->u.Processor.Flags = 0;
dataex->u.Processor.EfficiencyClass = 0;
dataex->u.Processor.GroupCount = 1;
dataex->u.Processor.GroupMask[0].Mask = mask;
@@ -1524,17 +1538,6 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
-static DWORD count_bits(ULONG_PTR mask)
-{
- DWORD count = 0;
- while (mask > 0)
- {
- mask >>= 1;
- count++;
- }
- return count;
-}
-
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
diff --git a/include/winnt.h b/include/winnt.h
index 54bf11dabd..862cc45291 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5982,6 +5982,8 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP
RelationAll = 0xffff
} LOGICAL_PROCESSOR_RELATIONSHIP;
+#define LTP_PC_SMT 0x1
+
typedef enum _PROCESSOR_CACHE_TYPE
{
CacheUnified,
--
2.14.4
June 14, 2018
[PATCH 2/4] ntdll: Report logical cores per physical core through mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e6458b98f2..0b69f7de44 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1325,8 +1325,16 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
(*pdata)[i].ProcessorMask |= mask;
return TRUE;
}
- }else
- i = *len;
+ }
+ else
+ {
+ for(i=0; i<*len; i++)
+ {
+ if ((*pdata)[i].Relationship==rel && (*pdata)[i].ProcessorMask==mask &&
+ (*pdata)[i].u.Reserved[1]==id)
+ return TRUE;
+ }
+ }
while(*len == *pmax_len)
{
@@ -1352,6 +1360,11 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->u.Processor.GroupMask[0].Mask |= mask;
return TRUE;
}
+ else if (rel == RelationProcessorCore && dataex->Relationship == rel &&
+ dataex->u.Processor.GroupMask[0].Mask == mask && dataex->u.Processor.Reserved[1] == id)
+ {
+ return TRUE;
+ }
ofs += dataex->Size;
}
@@ -1548,6 +1561,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=beg; i<=end; i++)
{
+ ULONG_PTR thread_mask = 0;
+
if(i > 8*sizeof(ULONG_PTR))
{
FIXME("skipping logical processor %d\n", i);
@@ -1568,15 +1583,16 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
}
- sprintf(name, core_info, i, "core_id");
+ /* Mask of logical threads sharing same physical core. */
+ sprintf(name, core_info, i, "thread_siblings");
f = fopen(name, "r");
if(f)
{
- fscanf(f, "%u", &r);
+ fscanf(f, "%lx", &thread_mask);
fclose(f);
}
- else r = i;
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, (ULONG_PTR)1 << i))
+ else thread_mask = 1<<i;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, thread_mask))
{
fclose(fcpu_list);
return STATUS_NO_MEMORY;
--
2.14.4
June 14, 2018
[PATCH 1/4] ntdll: Derive number of logical CPU cores from core mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dc0ce04f42..e6458b98f2 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1511,6 +1511,17 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
@@ -1643,7 +1654,6 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=0; i<len; i++){
if((*data)[i].Relationship == RelationProcessorCore){
all_cpus_mask |= (*data)[i].ProcessorMask;
- ++num_cpus;
}
}
}else{
@@ -1651,11 +1661,11 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*dataex) + i);
if(infoex->Relationship == RelationProcessorCore){
all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask;
- ++num_cpus;
}
i += infoex->Size;
}
}
+ num_cpus = count_bits(all_cpus_mask);
fnuma_list = fopen("/sys/devices/system/node/online", "r");
if(!fnuma_list)
--
2.14.4
June 14, 2018
[PATCH 0/4] ntdll: Improve logical core reporting on Linux
by Roderick Colenbrander
Hi all,
Recently I was helping a user troubleshoot some Ryzen performance issues.
As part of that still unresolved bug (Bugzilla 43277), I found out or CPU
core reporting code on Linux is not correct.
The summary is that we report all logical cores as if they were physical
CPU cores. Applications also can't determine whether they are dealing
with SMT / HyperThreaded cores. Essentially applications think there are
twice the number of physical cores.
The issue can easily be observed through various sample applications:
- Sysinternals core info application uses GetLogicalProcessorInformationEx:
https://docs.microsoft.com/en-us/sysinternals/downloads/coreinfo
- Example application on GetLogicalProcessorInformation:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683194(v=vs.85).…
The root cause of the issue is in how we enumerated CPU cores. We do so
by walking all logical cores in sysfs (/sys/devices/system/cpuX). Each core
we report as a physical core. We are not parsing the 'thread_siblings'
file, which tells us the mask of logical cores sharing a physical core.
This causes us to count cores twice. This happens both on AMD and Intel.
The patch series adjusts how we enumerate logical cores on Linux by
parsing 'thread_siblings' and making sure we don't add a new physical
core if a sibling earlier added a physical core for the same mask
and package. The cache parsing logic does something similar by parsing
'shared_cpu_map' and logical_proc_add_cache_info ignores already reported
caches as well.
In addition, we are now also reporting SMT capabilities to Flags of
GetLogicalProcessorInformation(Ex).
Thanks,
Roderick
Roderick Colenbrander (4):
ntdll: Derive number of logical CPU cores from core mask.
ntdll: Report logical cores per physical core through mask.
ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT
cores.
ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
dlls/ntdll/nt.c | 50 ++++++++++++++++++++++++++++++++++++++++----------
include/winnt.h | 2 ++
2 files changed, 42 insertions(+), 10 deletions(-)
--
2.14.4
June 14, 2018
Re: [PATCH 3/3] winedbg: Always start the interactive debugger in 64-bit mode if in a 64-bit prefix.
by Zebediah Figura
On 06/13/2018 04:34 PM, Zebediah Figura wrote:
> Fixes https://bugs.winehq.org/show_bug.cgi?id=45109
>
> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
> ---
> programs/winedbg/winedbg.c | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)
>
It occurs to me we don't want to do this until Mach-O support is
implemented for WoW64 in dbghelp. Please disregard this patch until then.
June 13, 2018
[PATCH 3/3] winedbg: Always start the interactive debugger in 64-bit mode if in a 64-bit prefix.
by Zebediah Figura
Fixes https://bugs.winehq.org/show_bug.cgi?id=45109
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
programs/winedbg/winedbg.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index 1ac4187..0e45186 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -632,6 +632,35 @@ static LONG CALLBACK top_filter( EXCEPTION_POINTERS *ptr )
return EXCEPTION_EXECUTE_HANDLER;
}
+static void restart_if_wow64(void)
+{
+ BOOL is_wow64;
+
+ if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64)
+ {
+ STARTUPINFOW si;
+ PROCESS_INFORMATION pi;
+ WCHAR filename[MAX_PATH];
+ void *redir;
+ DWORD exit_code;
+
+ memset( &si, 0, sizeof(si) );
+ si.cb = sizeof(si);
+ GetModuleFileNameW( 0, filename, MAX_PATH );
+
+ Wow64DisableWow64FsRedirection( &redir );
+ if (CreateProcessW( filename, GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
+ {
+ WINE_TRACE( "restarting %s\n", wine_dbgstr_w(filename) );
+ WaitForSingleObject( pi.hProcess, INFINITE );
+ GetExitCodeProcess( pi.hProcess, &exit_code );
+ ExitProcess( exit_code );
+ }
+ else WINE_ERR( "failed to restart 64-bit %s, err %d\n", wine_dbgstr_w(filename), GetLastError() );
+ Wow64RevertWow64FsRedirection( redir );
+ }
+}
+
int main(int argc, char** argv)
{
int retv = 0;
@@ -654,6 +683,7 @@ int main(int argc, char** argv)
if (argc && !strcmp(argv[0], "--gdb"))
{
+ restart_if_wow64();
retv = gdb_main(argc, argv);
if (retv == -1) dbg_winedbg_usage(FALSE);
return retv;
@@ -727,6 +757,8 @@ int main(int argc, char** argv)
case start_error_init: return -1;
}
+ restart_if_wow64();
+
dbg_start_interactive(hFile);
return 0;
--
2.7.4
June 13, 2018
[PATCH 2/3] winedbg/gdbproxy: Store the register map inside the be_cpu struct.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
programs/winedbg/be_arm.c | 24 +++
programs/winedbg/be_arm64.c | 41 ++++++
programs/winedbg/be_cpu.h | 10 ++
programs/winedbg/be_i386.c | 48 ++++++
programs/winedbg/be_ppc.c | 80 ++++++++++
programs/winedbg/be_x86_64.c | 64 ++++++++
programs/winedbg/debugger.h | 2 +
programs/winedbg/gdbproxy.c | 343 +++++--------------------------------------
8 files changed, 306 insertions(+), 306 deletions(-)
diff --git a/programs/winedbg/be_arm.c b/programs/winedbg/be_arm.c
index 9883476..0c65757 100644
--- a/programs/winedbg/be_arm.c
+++ b/programs/winedbg/be_arm.c
@@ -1904,6 +1904,28 @@ static BOOL be_arm_set_context(HANDLE thread, const dbg_ctx_t *ctx)
return SetThreadContext(thread, &ctx->ctx);
}
+#define REG(r,gs) {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs}
+
+static struct gdb_register be_arm_gdb_register_map[] = {
+ REG(R0, 4),
+ REG(R1, 4),
+ REG(R2, 4),
+ REG(R3, 4),
+ REG(R4, 4),
+ REG(R5, 4),
+ REG(R6, 4),
+ REG(R7, 4),
+ REG(R8, 4),
+ REG(R9, 4),
+ REG(R10, 4),
+ REG(R11, 4),
+ REG(R12, 4),
+ REG(Sp, 4),
+ REG(Lr, 4),
+ REG(Pc, 4),
+ REG(Cpsr, 4),
+};
+
struct backend_cpu be_arm =
{
IMAGE_FILE_MACHINE_ARMNT,
@@ -1931,5 +1953,7 @@ struct backend_cpu be_arm =
be_arm_fetch_float,
be_arm_store_integer,
be_arm_get_context,
+ be_arm_gdb_register_map,
+ ARRAY_SIZE(be_arm_gdb_register_map),
};
#endif
diff --git a/programs/winedbg/be_arm64.c b/programs/winedbg/be_arm64.c
index 418d6e0..40ef96b 100644
--- a/programs/winedbg/be_arm64.c
+++ b/programs/winedbg/be_arm64.c
@@ -293,6 +293,45 @@ static BOOL be_arm64_set_context(HANDLE thread, const dbg_ctx_t *ctx)
return SetThreadContext(thread, &ctx->ctx);
}
+#define REG(r,gs) {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs}
+
+static struct gdb_register be_arm64_gdb_register_map[] = {
+ REG(Cpsr, 4),
+ REG(u.s.X0, 8),
+ REG(u.s.X1, 8),
+ REG(u.s.X2, 8),
+ REG(u.s.X3, 8),
+ REG(u.s.X4, 8),
+ REG(u.s.X5, 8),
+ REG(u.s.X6, 8),
+ REG(u.s.X7, 8),
+ REG(u.s.X8, 8),
+ REG(u.s.X9, 8),
+ REG(u.s.X10, 8),
+ REG(u.s.X11, 8),
+ REG(u.s.X12, 8),
+ REG(u.s.X13, 8),
+ REG(u.s.X14, 8),
+ REG(u.s.X15, 8),
+ REG(u.s.X16, 8),
+ REG(u.s.X17, 8),
+ REG(u.s.X18, 8),
+ REG(u.s.X19, 8),
+ REG(u.s.X20, 8),
+ REG(u.s.X21, 8),
+ REG(u.s.X22, 8),
+ REG(u.s.X23, 8),
+ REG(u.s.X24, 8),
+ REG(u.s.X25, 8),
+ REG(u.s.X26, 8),
+ REG(u.s.X27, 8),
+ REG(u.s.X28, 8),
+ REG(u.s.Fp, 8),
+ REG(u.s.Lr, 8),
+ REG(Sp, 8),
+ REG(Pc, 8),
+};
+
struct backend_cpu be_arm64 =
{
IMAGE_FILE_MACHINE_ARM64,
@@ -320,5 +359,7 @@ struct backend_cpu be_arm64 =
be_arm64_fetch_float,
be_arm64_store_integer,
be_arm64_get_context,
+ be_arm64_gdb_register_map,
+ ARRAY_SIZE(be_arm64_gdb_register_map),
};
#endif
diff --git a/programs/winedbg/be_cpu.h b/programs/winedbg/be_cpu.h
index 1a67c06..ea559b4 100644
--- a/programs/winedbg/be_cpu.h
+++ b/programs/winedbg/be_cpu.h
@@ -22,6 +22,13 @@ enum be_cpu_addr {be_cpu_addr_pc, be_cpu_addr_stack, be_cpu_addr_frame};
enum be_xpoint_type {be_xpoint_break, be_xpoint_watch_exec, be_xpoint_watch_read,
be_xpoint_watch_write, be_xpoint_free=-1};
+struct gdb_register
+{
+ size_t ctx_offset;
+ size_t ctx_length;
+ size_t gdb_length;
+};
+
struct backend_cpu
{
const DWORD machine;
@@ -118,6 +125,9 @@ struct backend_cpu
BOOL (*get_context)(HANDLE thread, dbg_ctx_t *ctx);
BOOL (*set_context)(HANDLE thread, const dbg_ctx_t *ctx);
+
+ const struct gdb_register *gdb_register_map;
+ const size_t gdb_num_regs;
};
/* some handy functions for non segmented CPUs */
diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c
index 4e279ec..3a2b91a 100644
--- a/programs/winedbg/be_i386.c
+++ b/programs/winedbg/be_i386.c
@@ -866,6 +866,52 @@ static BOOL be_i386_set_context(HANDLE thread, const dbg_ctx_t *ctx)
return Wow64SetThreadContext(thread, &ctx->x86);
}
+#define REG(r,gs) {FIELD_OFFSET(WOW64_CONTEXT, r), sizeof(((WOW64_CONTEXT*)NULL)->r), gs}
+
+static struct gdb_register be_i386_gdb_register_map[] = {
+ REG(Eax, 4),
+ REG(Ecx, 4),
+ REG(Edx, 4),
+ REG(Ebx, 4),
+ REG(Esp, 4),
+ REG(Ebp, 4),
+ REG(Esi, 4),
+ REG(Edi, 4),
+ REG(Eip, 4),
+ REG(EFlags, 4),
+ REG(SegCs, 4),
+ REG(SegSs, 4),
+ REG(SegDs, 4),
+ REG(SegEs, 4),
+ REG(SegFs, 4),
+ REG(SegGs, 4),
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[ 0]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[10]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[20]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[30]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[40]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[50]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[60]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.RegisterArea[70]), 10, 10 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.ControlWord), 2, 4 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.StatusWord), 2, 4 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.TagWord), 2, 4 },
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.ErrorSelector), 2, 4 },
+ REG(FloatSave.ErrorOffset, 4 ),
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.DataSelector), 2, 4 },
+ REG(FloatSave.DataOffset, 4 ),
+ { FIELD_OFFSET(WOW64_CONTEXT, FloatSave.ErrorSelector)+2, 2, 4 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[0]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[1]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[2]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[3]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[4]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[5]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[6]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[7]), 16, 16 },
+ { FIELD_OFFSET(WOW64_CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, MxCsr), 4, 4 },
+};
+
struct backend_cpu be_i386 =
{
IMAGE_FILE_MACHINE_I386,
@@ -894,5 +940,7 @@ struct backend_cpu be_i386 =
be_i386_store_integer,
be_i386_get_context,
be_i386_set_context,
+ be_i386_gdb_register_map,
+ ARRAY_SIZE(be_i386_gdb_register_map),
};
#endif
diff --git a/programs/winedbg/be_ppc.c b/programs/winedbg/be_ppc.c
index 40aee55..b0e6f92 100644
--- a/programs/winedbg/be_ppc.c
+++ b/programs/winedbg/be_ppc.c
@@ -195,6 +195,84 @@ static BOOL be_ppc_set_context(HANDLE thread, const dbg_ctx_t *ctx)
return SetThreadContext(thread, &ctx->ctx);
}
+#define REG(r,gs,m) {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs, m}
+
+static struct gdb_register be_ppc_gdb_register_map[] = {
+ REG(Gpr0, 4),
+ REG(Gpr1, 4),
+ REG(Gpr2, 4),
+ REG(Gpr3, 4),
+ REG(Gpr4, 4),
+ REG(Gpr5, 4),
+ REG(Gpr6, 4),
+ REG(Gpr7, 4),
+ REG(Gpr8, 4),
+ REG(Gpr9, 4),
+ REG(Gpr10, 4),
+ REG(Gpr11, 4),
+ REG(Gpr12, 4),
+ REG(Gpr13, 4),
+ REG(Gpr14, 4),
+ REG(Gpr15, 4),
+ REG(Gpr16, 4),
+ REG(Gpr17, 4),
+ REG(Gpr18, 4),
+ REG(Gpr19, 4),
+ REG(Gpr20, 4),
+ REG(Gpr21, 4),
+ REG(Gpr22, 4),
+ REG(Gpr23, 4),
+ REG(Gpr24, 4),
+ REG(Gpr25, 4),
+ REG(Gpr26, 4),
+ REG(Gpr27, 4),
+ REG(Gpr28, 4),
+ REG(Gpr29, 4),
+ REG(Gpr30, 4),
+ REG(Gpr31, 4),
+ REG(Fpr0, 4),
+ REG(Fpr1, 4),
+ REG(Fpr2, 4),
+ REG(Fpr3, 4),
+ REG(Fpr4, 4),
+ REG(Fpr5, 4),
+ REG(Fpr6, 4),
+ REG(Fpr7, 4),
+ REG(Fpr8, 4),
+ REG(Fpr9, 4),
+ REG(Fpr10, 4),
+ REG(Fpr11, 4),
+ REG(Fpr12, 4),
+ REG(Fpr13, 4),
+ REG(Fpr14, 4),
+ REG(Fpr15, 4),
+ REG(Fpr16, 4),
+ REG(Fpr17, 4),
+ REG(Fpr18, 4),
+ REG(Fpr19, 4),
+ REG(Fpr20, 4),
+ REG(Fpr21, 4),
+ REG(Fpr22, 4),
+ REG(Fpr23, 4),
+ REG(Fpr24, 4),
+ REG(Fpr25, 4),
+ REG(Fpr26, 4),
+ REG(Fpr27, 4),
+ REG(Fpr28, 4),
+ REG(Fpr29, 4),
+ REG(Fpr30, 4),
+ REG(Fpr31, 4),
+
+ REG(Iar, 4),
+ REG(Msr, 4),
+ REG(Cr, 4),
+ REG(Lr, 4),
+ REG(Ctr, 4),
+ REG(Xer, 4),
+ /* FIXME: MQ is missing? FIELD_OFFSET(CONTEXT, Mq), */
+ /* see gdb/nlm/ppc.c */
+};
+
struct backend_cpu be_ppc =
{
IMAGE_FILE_MACHINE_POWERPC,
@@ -223,5 +301,7 @@ struct backend_cpu be_ppc =
be_ppc_store_integer,
be_ppc_get_context,
be_ppc_set_context,
+ be_ppc_gdb_register_map,
+ ARRAY_SIZE(be_ppc_gdb_register_map),
};
#endif
diff --git a/programs/winedbg/be_x86_64.c b/programs/winedbg/be_x86_64.c
index 15f84a6..b7f75c6 100644
--- a/programs/winedbg/be_x86_64.c
+++ b/programs/winedbg/be_x86_64.c
@@ -689,6 +689,68 @@ static BOOL be_x86_64_set_context(HANDLE thread, const dbg_ctx_t *ctx)
return SetThreadContext(thread, &ctx->ctx);
}
+#define REG(r,gs) {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs}
+
+static struct gdb_register be_x86_64_gdb_register_map[] = {
+ REG(Rax, 8),
+ REG(Rbx, 8),
+ REG(Rcx, 8),
+ REG(Rdx, 8),
+ REG(Rsi, 8),
+ REG(Rdi, 8),
+ REG(Rbp, 8),
+ REG(Rsp, 8),
+ REG(R8, 8),
+ REG(R9, 8),
+ REG(R10, 8),
+ REG(R11, 8),
+ REG(R12, 8),
+ REG(R13, 8),
+ REG(R14, 8),
+ REG(R15, 8),
+ REG(Rip, 8),
+ REG(EFlags, 4),
+ REG(SegCs, 4),
+ REG(SegSs, 4),
+ REG(SegDs, 4),
+ REG(SegEs, 4),
+ REG(SegFs, 4),
+ REG(SegGs, 4),
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 0]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 1]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 2]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 3]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 4]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 5]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 6]), 10, 10 },
+ { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 7]), 10, 10 },
+ REG(u.FltSave.ControlWord, 4),
+ REG(u.FltSave.StatusWord, 4),
+ REG(u.FltSave.TagWord, 4),
+ REG(u.FltSave.ErrorSelector, 4),
+ REG(u.FltSave.ErrorOffset, 4),
+ REG(u.FltSave.DataSelector, 4),
+ REG(u.FltSave.DataOffset, 4),
+ REG(u.FltSave.ErrorOpcode, 4),
+ REG(u.s.Xmm0, 16),
+ REG(u.s.Xmm1, 16),
+ REG(u.s.Xmm2, 16),
+ REG(u.s.Xmm3, 16),
+ REG(u.s.Xmm4, 16),
+ REG(u.s.Xmm5, 16),
+ REG(u.s.Xmm6, 16),
+ REG(u.s.Xmm7, 16),
+ REG(u.s.Xmm8, 16),
+ REG(u.s.Xmm9, 16),
+ REG(u.s.Xmm10, 16),
+ REG(u.s.Xmm11, 16),
+ REG(u.s.Xmm12, 16),
+ REG(u.s.Xmm13, 16),
+ REG(u.s.Xmm14, 16),
+ REG(u.s.Xmm15, 16),
+ REG(u.FltSave.MxCsr, 4),
+};
+
struct backend_cpu be_x86_64 =
{
IMAGE_FILE_MACHINE_AMD64,
@@ -717,5 +779,7 @@ struct backend_cpu be_x86_64 =
be_x86_64_store_integer,
be_x86_64_get_context,
be_x86_64_set_context,
+ be_x86_64_gdb_register_map,
+ ARRAY_SIZE(be_x86_64_gdb_register_map),
};
#endif
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 490bd06..3fc8daa 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -39,6 +39,8 @@
#include "oaidl.h"
#include <wine/list.h>
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
#define ADDRSIZE (dbg_curr_process->be_cpu->pointer_size)
#define ADDRWIDTH (ADDRSIZE * 2)
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 81cd7de..869d56b 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -183,233 +183,12 @@ static unsigned char checksum(const char* ptr, int len)
return cksum;
}
-/* =============================================== *
- * C P U H A N D L E R S *
- * =============================================== *
- */
-
-/* This struct helps us to manage the different representations of a register:
- * ctx_offset and ctx_length are the location and size in Win32 CONTEXT
- * gdb_length is the length gdb expects on the wire
- * As the two sizes could be different, we have to convert between the two
- * (for example, on x86_64, Seg?s are 4 bytes on the wire and 2 in CONTEXT)
- */
-struct cpu_register
-{
- size_t ctx_offset;
- size_t ctx_length;
- size_t gdb_length;
-};
-
-#define REG(r,gs) {FIELD_OFFSET(CONTEXT, r), sizeof(((CONTEXT*)NULL)->r), gs}
-
#ifdef __i386__
-typedef struct DECLSPEC_ALIGN(16) _M128A {
- ULONGLONG Low;
- LONGLONG High;
-} M128A, *PM128A;
-
-typedef struct _XMM_SAVE_AREA32 {
- WORD ControlWord; /* 000 */
- WORD StatusWord; /* 002 */
- BYTE TagWord; /* 004 */
- BYTE Reserved1; /* 005 */
- WORD ErrorOpcode; /* 006 */
- DWORD ErrorOffset; /* 008 */
- WORD ErrorSelector; /* 00c */
- WORD Reserved2; /* 00e */
- DWORD DataOffset; /* 010 */
- WORD DataSelector; /* 014 */
- WORD Reserved3; /* 016 */
- DWORD MxCsr; /* 018 */
- DWORD MxCsr_Mask; /* 01c */
- M128A FloatRegisters[8]; /* 020 */
- M128A XmmRegisters[16]; /* 0a0 */
- BYTE Reserved4[96]; /* 1a0 */
-} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
-
static const char target_xml[] = "";
-static struct cpu_register cpu_register_map[] = {
- REG(Eax, 4),
- REG(Ecx, 4),
- REG(Edx, 4),
- REG(Ebx, 4),
- REG(Esp, 4),
- REG(Ebp, 4),
- REG(Esi, 4),
- REG(Edi, 4),
- REG(Eip, 4),
- REG(EFlags, 4),
- REG(SegCs, 4),
- REG(SegSs, 4),
- REG(SegDs, 4),
- REG(SegEs, 4),
- REG(SegFs, 4),
- REG(SegGs, 4),
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[ 0]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[10]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[20]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[30]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[40]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[50]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[60]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.RegisterArea[70]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, FloatSave.ControlWord), 2, 4 },
- { FIELD_OFFSET(CONTEXT, FloatSave.StatusWord), 2, 4 },
- { FIELD_OFFSET(CONTEXT, FloatSave.TagWord), 2, 4 },
- { FIELD_OFFSET(CONTEXT, FloatSave.ErrorSelector), 2, 4 },
- REG(FloatSave.ErrorOffset, 4 ),
- { FIELD_OFFSET(CONTEXT, FloatSave.DataSelector), 2, 4 },
- REG(FloatSave.DataOffset, 4 ),
- { FIELD_OFFSET(CONTEXT, FloatSave.ErrorSelector)+2, 2, 4 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[0]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[1]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[2]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[3]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[4]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[5]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[6]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, XmmRegisters[7]), 16, 16 },
- { FIELD_OFFSET(CONTEXT, ExtendedRegisters) + FIELD_OFFSET(XMM_SAVE_AREA32, MxCsr), 4, 4 },
-};
#elif defined(__powerpc__)
static const char target_xml[] = "";
-static struct cpu_register cpu_register_map[] = {
- REG(Gpr0, 4),
- REG(Gpr1, 4),
- REG(Gpr2, 4),
- REG(Gpr3, 4),
- REG(Gpr4, 4),
- REG(Gpr5, 4),
- REG(Gpr6, 4),
- REG(Gpr7, 4),
- REG(Gpr8, 4),
- REG(Gpr9, 4),
- REG(Gpr10, 4),
- REG(Gpr11, 4),
- REG(Gpr12, 4),
- REG(Gpr13, 4),
- REG(Gpr14, 4),
- REG(Gpr15, 4),
- REG(Gpr16, 4),
- REG(Gpr17, 4),
- REG(Gpr18, 4),
- REG(Gpr19, 4),
- REG(Gpr20, 4),
- REG(Gpr21, 4),
- REG(Gpr22, 4),
- REG(Gpr23, 4),
- REG(Gpr24, 4),
- REG(Gpr25, 4),
- REG(Gpr26, 4),
- REG(Gpr27, 4),
- REG(Gpr28, 4),
- REG(Gpr29, 4),
- REG(Gpr30, 4),
- REG(Gpr31, 4),
- REG(Fpr0, 4),
- REG(Fpr1, 4),
- REG(Fpr2, 4),
- REG(Fpr3, 4),
- REG(Fpr4, 4),
- REG(Fpr5, 4),
- REG(Fpr6, 4),
- REG(Fpr7, 4),
- REG(Fpr8, 4),
- REG(Fpr9, 4),
- REG(Fpr10, 4),
- REG(Fpr11, 4),
- REG(Fpr12, 4),
- REG(Fpr13, 4),
- REG(Fpr14, 4),
- REG(Fpr15, 4),
- REG(Fpr16, 4),
- REG(Fpr17, 4),
- REG(Fpr18, 4),
- REG(Fpr19, 4),
- REG(Fpr20, 4),
- REG(Fpr21, 4),
- REG(Fpr22, 4),
- REG(Fpr23, 4),
- REG(Fpr24, 4),
- REG(Fpr25, 4),
- REG(Fpr26, 4),
- REG(Fpr27, 4),
- REG(Fpr28, 4),
- REG(Fpr29, 4),
- REG(Fpr30, 4),
- REG(Fpr31, 4),
-
- REG(Iar, 4),
- REG(Msr, 4),
- REG(Cr, 4),
- REG(Lr, 4),
- REG(Ctr, 4),
- REG(Xer, 4),
- /* FIXME: MQ is missing? FIELD_OFFSET(CONTEXT, Mq), */
- /* see gdb/nlm/ppc.c */
-};
#elif defined(__x86_64__)
static const char target_xml[] = "";
-static struct cpu_register cpu_register_map[] = {
- REG(Rax, 8),
- REG(Rbx, 8),
- REG(Rcx, 8),
- REG(Rdx, 8),
- REG(Rsi, 8),
- REG(Rdi, 8),
- REG(Rbp, 8),
- REG(Rsp, 8),
- REG(R8, 8),
- REG(R9, 8),
- REG(R10, 8),
- REG(R11, 8),
- REG(R12, 8),
- REG(R13, 8),
- REG(R14, 8),
- REG(R15, 8),
- REG(Rip, 8),
- REG(EFlags, 4),
- REG(SegCs, 4),
- REG(SegSs, 4),
- REG(SegDs, 4),
- REG(SegEs, 4),
- REG(SegFs, 4),
- REG(SegGs, 4),
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 0]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 1]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 2]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 3]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 4]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 5]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 6]), 10, 10 },
- { FIELD_OFFSET(CONTEXT, u.FltSave.FloatRegisters[ 7]), 10, 10 },
- REG(u.FltSave.ControlWord, 4),
- REG(u.FltSave.StatusWord, 4),
- REG(u.FltSave.TagWord, 4),
- REG(u.FltSave.ErrorSelector, 4),
- REG(u.FltSave.ErrorOffset, 4),
- REG(u.FltSave.DataSelector, 4),
- REG(u.FltSave.DataOffset, 4),
- REG(u.FltSave.ErrorOpcode, 4),
- REG(u.s.Xmm0, 16),
- REG(u.s.Xmm1, 16),
- REG(u.s.Xmm2, 16),
- REG(u.s.Xmm3, 16),
- REG(u.s.Xmm4, 16),
- REG(u.s.Xmm5, 16),
- REG(u.s.Xmm6, 16),
- REG(u.s.Xmm7, 16),
- REG(u.s.Xmm8, 16),
- REG(u.s.Xmm9, 16),
- REG(u.s.Xmm10, 16),
- REG(u.s.Xmm11, 16),
- REG(u.s.Xmm12, 16),
- REG(u.s.Xmm13, 16),
- REG(u.s.Xmm14, 16),
- REG(u.s.Xmm15, 16),
- REG(u.FltSave.MxCsr, 4),
-};
#elif defined(__arm__)
static const char target_xml[] =
"l <target><architecture>arm</architecture>\n"
@@ -432,96 +211,43 @@ static const char target_xml[] =
" <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n"
" <reg name=\"cpsr\" bitsize=\"32\"/>\n"
"</feature></target>\n";
-
-static struct cpu_register cpu_register_map[] = {
- REG(R0, 4),
- REG(R1, 4),
- REG(R2, 4),
- REG(R3, 4),
- REG(R4, 4),
- REG(R5, 4),
- REG(R6, 4),
- REG(R7, 4),
- REG(R8, 4),
- REG(R9, 4),
- REG(R10, 4),
- REG(R11, 4),
- REG(R12, 4),
- REG(Sp, 4),
- REG(Lr, 4),
- REG(Pc, 4),
- REG(Cpsr, 4),
-};
#elif defined(__aarch64__)
static const char target_xml[] = "";
-static struct cpu_register cpu_register_map[] = {
- REG(Cpsr, 4),
- REG(u.s.X0, 8),
- REG(u.s.X1, 8),
- REG(u.s.X2, 8),
- REG(u.s.X3, 8),
- REG(u.s.X4, 8),
- REG(u.s.X5, 8),
- REG(u.s.X6, 8),
- REG(u.s.X7, 8),
- REG(u.s.X8, 8),
- REG(u.s.X9, 8),
- REG(u.s.X10, 8),
- REG(u.s.X11, 8),
- REG(u.s.X12, 8),
- REG(u.s.X13, 8),
- REG(u.s.X14, 8),
- REG(u.s.X15, 8),
- REG(u.s.X16, 8),
- REG(u.s.X17, 8),
- REG(u.s.X18, 8),
- REG(u.s.X19, 8),
- REG(u.s.X20, 8),
- REG(u.s.X21, 8),
- REG(u.s.X22, 8),
- REG(u.s.X23, 8),
- REG(u.s.X24, 8),
- REG(u.s.X25, 8),
- REG(u.s.X26, 8),
- REG(u.s.X27, 8),
- REG(u.s.X28, 8),
- REG(u.s.Fp, 8),
- REG(u.s.Lr, 8),
- REG(Sp, 8),
- REG(Pc, 8),
-};
#else
# error Define the registers map for your CPU
#endif
-#undef REG
-static const size_t cpu_num_regs = (sizeof(cpu_register_map) / sizeof(cpu_register_map[0]));
-
-static inline void* cpu_register_ptr(dbg_ctx_t *ctx, unsigned idx)
+static inline void* cpu_register_ptr(struct gdb_context *gdbctx,
+ dbg_ctx_t *ctx, unsigned idx)
{
- assert(idx < cpu_num_regs);
- return (char*)ctx + cpu_register_map[idx].ctx_offset;
+ assert(idx < gdbctx->process->be_cpu->gdb_num_regs);
+ return (char*)ctx + gdbctx->process->be_cpu->gdb_register_map[idx].ctx_offset;
}
-static inline DWORD64 cpu_register(dbg_ctx_t *ctx, unsigned idx)
+static inline DWORD64 cpu_register(struct gdb_context *gdbctx,
+ dbg_ctx_t *ctx, unsigned idx)
{
- switch (cpu_register_map[idx].ctx_length)
+ switch (gdbctx->process->be_cpu->gdb_register_map[idx].ctx_length)
{
- case 1: return *(BYTE*)cpu_register_ptr(ctx, idx);
- case 2: return *(WORD*)cpu_register_ptr(ctx, idx);
- case 4: return *(DWORD*)cpu_register_ptr(ctx, idx);
- case 8: return *(DWORD64*)cpu_register_ptr(ctx, idx);
+ case 1: return *(BYTE*)cpu_register_ptr(gdbctx, ctx, idx);
+ case 2: return *(WORD*)cpu_register_ptr(gdbctx, ctx, idx);
+ case 4: return *(DWORD*)cpu_register_ptr(gdbctx, ctx, idx);
+ case 8: return *(DWORD64*)cpu_register_ptr(gdbctx, ctx, idx);
default:
- fprintf(stderr, "got unexpected size: %u\n", (unsigned)cpu_register_map[idx].ctx_length);
+ fprintf(stderr, "got unexpected size: %u\n",
+ (unsigned)gdbctx->process->be_cpu->gdb_register_map[idx].ctx_length);
assert(0);
return 0;
}
}
-static inline void cpu_register_hex_from(dbg_ctx_t* ctx, unsigned idx, const char **phex)
+static inline void cpu_register_hex_from(struct gdb_context *gdbctx,
+ dbg_ctx_t* ctx, unsigned idx, const char **phex)
{
+ const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
+
if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length)
- hex_from(cpu_register_ptr(ctx, idx), *phex, cpu_register_map[idx].gdb_length);
+ hex_from(cpu_register_ptr(gdbctx, ctx, idx), *phex, cpu_register_map[idx].gdb_length);
else
{
DWORD64 val = 0;
@@ -536,10 +262,10 @@ static inline void cpu_register_hex_from(dbg_ctx_t* ctx, unsigned idx, const cha
}
switch (cpu_register_map[idx].ctx_length)
{
- case 1: *(BYTE*)cpu_register_ptr(ctx, idx) = (BYTE)val; break;
- case 2: *(WORD*)cpu_register_ptr(ctx, idx) = (WORD)val; break;
- case 4: *(DWORD*)cpu_register_ptr(ctx, idx) = (DWORD)val; break;
- case 8: *(DWORD64*)cpu_register_ptr(ctx, idx) = val; break;
+ case 1: *(BYTE*)cpu_register_ptr(gdbctx, ctx, idx) = (BYTE)val; break;
+ case 2: *(WORD*)cpu_register_ptr(gdbctx, ctx, idx) = (WORD)val; break;
+ case 4: *(DWORD*)cpu_register_ptr(gdbctx, ctx, idx) = (DWORD)val; break;
+ case 8: *(DWORD64*)cpu_register_ptr(gdbctx, ctx, idx) = val; break;
default: assert(0);
}
}
@@ -1078,11 +804,14 @@ static enum packet_return packet_reply_error(struct gdb_context* gdbctx, int err
static inline void packet_reply_register_hex_to(struct gdb_context* gdbctx, unsigned idx)
{
+ const struct gdb_register *cpu_register_map = gdbctx->process->be_cpu->gdb_register_map;
+
if (cpu_register_map[idx].gdb_length == cpu_register_map[idx].ctx_length)
- packet_reply_hex_to(gdbctx, cpu_register_ptr(&gdbctx->context, idx), cpu_register_map[idx].gdb_length);
+ packet_reply_hex_to(gdbctx, cpu_register_ptr(gdbctx, &gdbctx->context, idx),
+ cpu_register_map[idx].gdb_length);
else
{
- DWORD64 val = cpu_register(&gdbctx->context, idx);
+ DWORD64 val = cpu_register(gdbctx, &gdbctx->context, idx);
unsigned i;
for (i = 0; i < cpu_register_map[idx].gdb_length; i++)
@@ -1117,7 +846,7 @@ static enum packet_return packet_reply_status(struct gdb_context* gdbctx)
packet_reply_val(gdbctx, dbg_curr_thread->tid, 4);
packet_reply_catc(gdbctx, ';');
- for (i = 0; i < cpu_num_regs; i++)
+ for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++)
{
/* FIXME: this call will also grow the buffer...
* unneeded, but not harmful
@@ -1453,14 +1182,16 @@ static enum packet_return packet_read_registers(struct gdb_context* gdbctx)
}
packet_reply_open(gdbctx);
- for (i = 0; i < cpu_num_regs; i++)
+ for (i = 0; i < gdbctx->process->be_cpu->gdb_num_regs; i++)
packet_reply_register_hex_to(gdbctx, i);
+
packet_reply_close(gdbctx);
return packet_done;
}
static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
{
+ const size_t cpu_num_regs = gdbctx->process->be_cpu->gdb_num_regs;
unsigned i;
dbg_ctx_t ctx;
dbg_ctx_t *pctx = &gdbctx->context;
@@ -1476,7 +1207,7 @@ static enum packet_return packet_write_registers(struct gdb_context* gdbctx)
ptr = gdbctx->in_packet;
for (i = 0; i < cpu_num_regs; i++)
- cpu_register_hex_from(pctx, i, &ptr);
+ cpu_register_hex_from(gdbctx, pctx, i, &ptr);
if (pctx != &gdbctx->context &&
!gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx))
@@ -1621,7 +1352,7 @@ static enum packet_return packet_read_register(struct gdb_context* gdbctx)
assert(gdbctx->in_trap);
reg = hex_to_int(gdbctx->in_packet, gdbctx->in_packet_len);
- if (reg >= cpu_num_regs)
+ if (reg >= gdbctx->process->be_cpu->gdb_num_regs)
{
if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
fprintf(stderr, "Register out of bounds %x\n", reg);
@@ -1634,9 +1365,9 @@ static enum packet_return packet_read_register(struct gdb_context* gdbctx)
}
if (gdbctx->trace & GDBPXY_TRC_COMMAND)
{
- if (cpu_register_map[reg].ctx_length <= sizeof(DWORD64))
+ if (gdbctx->process->be_cpu->gdb_register_map[reg].ctx_length <= sizeof(DWORD64))
fprintf(stderr, "Read register %x => %08x%08x\n", reg,
- (unsigned)(cpu_register(pctx, reg) >> 32), (unsigned)cpu_register(pctx, reg));
+ (unsigned)(cpu_register(gdbctx, pctx, reg) >> 32), (unsigned)cpu_register(gdbctx, pctx, reg));
else
fprintf(stderr, "Read register %x\n", reg);
}
@@ -1656,7 +1387,7 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
assert(gdbctx->in_trap);
reg = strtoul(gdbctx->in_packet, &ptr, 16);
- if (ptr == NULL || reg >= cpu_num_regs || *ptr++ != '=')
+ if (ptr == NULL || reg >= gdbctx->process->be_cpu->gdb_num_regs || *ptr++ != '=')
{
if (gdbctx->trace & GDBPXY_TRC_COMMAND_ERROR)
fprintf(stderr, "Invalid register index %s\n", gdbctx->in_packet);
@@ -1677,7 +1408,7 @@ static enum packet_return packet_write_register(struct gdb_context* gdbctx)
return packet_error;
}
- cpu_register_hex_from(pctx, reg, (const char**)&ptr);
+ cpu_register_hex_from(gdbctx, pctx, reg, (const char**)&ptr);
if (pctx != &gdbctx->context &&
!gdbctx->process->be_cpu->set_context(gdbctx->other_thread->handle, pctx))
{
--
2.7.4
June 13, 2018
[PATCH 1/3] winedbg: Implement debugging 32-bit processes on x86_64.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
programs/winedbg/be_i386.c | 22 ++++++++++++----------
programs/winedbg/db_disasm.c | 4 ++--
programs/winedbg/winedbg.c | 21 ++++++++-------------
3 files changed, 22 insertions(+), 25 deletions(-)
diff --git a/programs/winedbg/be_i386.c b/programs/winedbg/be_i386.c
index f46ebb1..4e279ec 100644
--- a/programs/winedbg/be_i386.c
+++ b/programs/winedbg/be_i386.c
@@ -21,7 +21,7 @@
#include "debugger.h"
#include "wine/debug.h"
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
@@ -33,6 +33,7 @@ extern void be_i386_disasm_one_insn(ADDRESS64* addr, int display);
#define IS_VM86_MODE(ctx) (ctx->EFlags & V86_FLAG)
+#ifndef __x86_64__
typedef struct DECLSPEC_ALIGN(16) _M128A {
ULONGLONG Low;
LONGLONG High;
@@ -56,6 +57,7 @@ typedef struct _XMM_SAVE_AREA32 {
M128A XmmRegisters[16]; /* 0a0 */
BYTE Reserved4[96]; /* 1a0 */
} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
+#endif
static ADDRESS_MODE get_selector_type(HANDLE hThread, const WOW64_CONTEXT *ctx, WORD sel)
{
@@ -77,18 +79,18 @@ static void* be_i386_linearize(HANDLE hThread, const ADDRESS64* addr)
switch (addr->Mode)
{
case AddrModeReal:
- return (void*)((DWORD)(LOWORD(addr->Segment) << 4) + (DWORD)addr->Offset);
+ return (void*)((DWORD_PTR)(LOWORD(addr->Segment) << 4) + (DWORD_PTR)addr->Offset);
case AddrMode1632:
if (!(addr->Segment & 4) || ((addr->Segment >> 3) < 17))
- return (void*)(DWORD)addr->Offset;
+ return (void*)(DWORD_PTR)addr->Offset;
/* fall through */
case AddrMode1616:
if (!dbg_curr_process->process_io->get_selector(hThread, addr->Segment, &le)) return NULL;
return (void*)((le.HighWord.Bits.BaseHi << 24) +
(le.HighWord.Bits.BaseMid << 16) + le.BaseLow +
- (DWORD)addr->Offset);
+ (DWORD_PTR)addr->Offset);
case AddrModeFlat:
- return (void*)(DWORD)addr->Offset;
+ return (void*)(DWORD_PTR)addr->Offset;
}
return NULL;
}
@@ -502,7 +504,7 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
if (!fetch_value((const char*)insn + 1, operand_size, &delta))
return FALSE;
callee->Segment = dbg_context.x86.SegCs;
- callee->Offset = (DWORD)insn + 1 + (operand_size / 8) + delta;
+ callee->Offset = (DWORD_PTR)insn + 1 + (operand_size / 8) + delta;
return TRUE;
case 0x9a: /* absolute far call */
@@ -589,11 +591,11 @@ static BOOL be_i386_is_func_call(const void* insn, ADDRESS64* callee)
}
if (((ch >> 3) & 0x07) == 0x03) /* LCALL */
{
- if (!dbg_read_memory((const char*)dst + operand_size, &segment, sizeof(segment)))
+ if (!dbg_read_memory((const char*)(UINT_PTR)dst + operand_size, &segment, sizeof(segment)))
return FALSE;
}
else segment = dbg_context.x86.SegCs;
- if (!dbg_read_memory((const char*)dst, &delta, sizeof(delta)))
+ if (!dbg_read_memory((const char*)(UINT_PTR)dst, &delta, sizeof(delta)))
return FALSE;
callee->Mode = get_selector_type(dbg_curr_thread->handle, &dbg_context.x86,
segment);
@@ -643,7 +645,7 @@ static BOOL be_i386_is_jump(const void* insn, ADDRESS64* jumpee)
if (!fetch_value((const char*)insn + 1, operand_size, &delta))
return FALSE;
jumpee->Segment = dbg_context.x86.SegCs;
- jumpee->Offset = (DWORD)insn + 1 + (operand_size / 8) + delta;
+ jumpee->Offset = (DWORD_PTR)insn + 1 + (operand_size / 8) + delta;
return TRUE;
default: WINE_FIXME("unknown %x\n", ch); return FALSE;
}
@@ -733,7 +735,7 @@ static BOOL be_i386_insert_Xpoint(HANDLE hProcess, const struct be_process_io* p
bits = DR7_RW_WRITE;
hw_bp:
if ((reg = be_i386_get_unused_DR(ctx, &pr)) == -1) return FALSE;
- *pr = (DWORD)addr;
+ *pr = (DWORD_PTR)addr;
if (type != be_xpoint_watch_exec) switch (size)
{
case 4: bits |= DR7_LEN_4; break;
diff --git a/programs/winedbg/db_disasm.c b/programs/winedbg/db_disasm.c
index 9bdfb90..f57f009 100644
--- a/programs/winedbg/db_disasm.c
+++ b/programs/winedbg/db_disasm.c
@@ -64,7 +64,7 @@
#include "debugger.h"
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
/*
* Switch to disassemble 16-bit code.
@@ -1225,7 +1225,7 @@ static void db_print_address(const char *seg, int size, struct i_addr *addrp, in
void* a2;
dbg_printf("0x%x -> ", addrp->disp);
- if (!dbg_read_memory((void*)addrp->disp, &a1, sizeof(a1))) {
+ if (!dbg_read_memory((void*)(INT_PTR)addrp->disp, &a1, sizeof(a1))) {
dbg_printf("(invalid source)");
} else if (!dbg_read_memory(a1, &a2, sizeof(a2))) {
dbg_printf("(invalid destination)");
diff --git a/programs/winedbg/winedbg.c b/programs/winedbg/winedbg.c
index b5ffd76..1ac4187 100644
--- a/programs/winedbg/winedbg.c
+++ b/programs/winedbg/winedbg.c
@@ -284,6 +284,7 @@ extern struct backend_cpu be_i386;
#elif defined(__powerpc__)
extern struct backend_cpu be_ppc;
#elif defined(__x86_64__)
+extern struct backend_cpu be_i386;
extern struct backend_cpu be_x86_64;
#elif defined(__arm__) && !defined(__ARMEB__)
extern struct backend_cpu be_arm;
@@ -296,21 +297,13 @@ extern struct backend_cpu be_arm64;
struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid, HANDLE h)
{
struct dbg_process* p;
+ BOOL wow64;
if ((p = dbg_get_process(pid)))
- {
- if (p->handle != 0)
- {
- WINE_ERR("Process (%04x) is already defined\n", pid);
- }
- else
- {
- p->handle = h;
- p->process_io = pio;
- p->imageName = NULL;
- }
return p;
- }
+
+ if (!h)
+ h = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!(p = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dbg_process)))) return NULL;
p->handle = h;
@@ -333,12 +326,14 @@ struct dbg_process* dbg_add_process(const struct be_process_io* pio, DWORD pid,
list_add_head(&dbg_process_list, &p->entry);
+ IsWow64Process(h, &wow64);
+
#ifdef __i386__
p->be_cpu = &be_i386;
#elif defined(__powerpc__)
p->be_cpu = &be_ppc;
#elif defined(__x86_64__)
- p->be_cpu = &be_x86_64;
+ p->be_cpu = wow64 ? &be_i386 : &be_x86_64;
#elif defined(__arm__) && !defined(__ARMEB__)
p->be_cpu = &be_arm;
#elif defined(__aarch64__) && !defined(__AARCH64EB__)
--
2.7.4
June 13, 2018
Re: [PATCH 2/5] wined3d: Get rid of unnecessary enum wined3d_data_type values.
by Józef Kucia
On Wed, Jun 13, 2018 at 8:29 PM, Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
> 2018-06-13 10:37 GMT+02:00 Józef Kucia <joseph.kucia(a)gmail.com>:
>> On Tue, Jun 12, 2018 at 6:41 PM, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
>>> diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
>>> index 20d4f0773dd..a2c3f00559a 100644
>>> --- a/dlls/wined3d/shader.c
>>> +++ b/dlls/wined3d/shader.c
>>> @@ -2134,14 +2134,6 @@ static void shader_dump_decl_usage(struct wined3d_string_buffer *buffer,
>>> shader_addline(buffer, " (uint)");
>>> break;
>>>
>>> - case WINED3D_DATA_UNORM:
>>> - shader_addline(buffer, " (unorm)");
>>> - break;
>>> -
>>> - case WINED3D_DATA_SNORM:
>>> - shader_addline(buffer, " (snorm)");
>>> - break;
>>> -
>>
>> I don't like that it won't print the correct data type for
>> declarations. For example, after the patch "dcl_uav_typed_texture2d
>> (snorm) u0" is "dcl_uav_typed_texture2d (float) u0".
>
> Yeah, it's a downside of the "simplification". Would printing
> something more generic like "(float / unorm / snorm)" work for you?
> Any other idea?
Perhaps it's possible to keep wined3d_data_type for
wined3d_shader_semantic, or preserve the type information in
wined3d_shader_semantic differently.
June 13, 2018
Re: [PATCH 6/6] dxgi: Get supported feature levels from wined3d caps.
by Józef Kucia
On Wed, Jun 13, 2018 at 8:31 PM, Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
> 2018-06-13 12:24 GMT+02:00 Józef Kucia <jkucia(a)codeweavers.com>:
>
>> On a side note, handling of feature levels 9_x appears to be incorrect
>> (AFAIK feature levels 9_x always use SM2 shaders).
>
> True, but it's complicated...
> Looking around https://msdn.microsoft.com/en-us/library/windows/desktop/ff476876(v=vs.85).…
> you can see that feature level 9_3 e.g. mandates support for max
> texture size >= 4096, which is only guaranteed by SM3-level hardware
> (https://msdn.microsoft.com/en-us/library/windows/desktop/bb219845(v=vs.85).…)
> IIRC there were a few of those, which is why I decided to require SM3
> for 9_3 even though the shaders themselves are going to be SM2 only.
>
Right, feature level checks should not be based solely on shader model versions.
June 13, 2018
[PATCH] winex11.drv: Refcount the vulkan surface window
by Andrew Eikum
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
Modeled after the opengl refcounting. This prevents us getting X
errors from using client_window after it's been destroyed.
dlls/winex11.drv/vulkan.c | 61 ++++++++++++++++++++++++++++++++++-----
dlls/winex11.drv/window.c | 1 +
dlls/winex11.drv/x11drv.h | 1 +
3 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c
index 7e252326b5..7eca31bdea 100644
--- a/dlls/winex11.drv/vulkan.c
+++ b/dlls/winex11.drv/vulkan.c
@@ -41,11 +41,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
#ifdef SONAME_LIBVULKAN
+static CRITICAL_SECTION context_section;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &context_section,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": context_section") }
+};
+static CRITICAL_SECTION context_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+static XContext vulkan_hwnd_context;
+
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
#define VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR 1000004000
struct wine_vk_surface
{
+ LONG ref;
Window window;
VkSurfaceKHR surface; /* native surface */
};
@@ -115,6 +127,8 @@ static BOOL WINAPI wine_vk_init(INIT_ONCE *once, void *param, void **context)
LOAD_FUNCPTR(vkQueuePresentKHR)
#undef LOAD_FUNCPTR
+ vulkan_hwnd_context = XUniqueContext();
+
return TRUE;
fail:
@@ -171,20 +185,35 @@ static VkResult wine_vk_instance_convert_create_info(const VkInstanceCreateInfo
return VK_SUCCESS;
}
-static void wine_vk_surface_destroy(VkInstance instance, struct wine_vk_surface *surface)
+static struct wine_vk_surface *wine_vk_surface_grab(struct wine_vk_surface *surface)
{
- if (!surface)
+ InterlockedIncrement(&surface->ref);
+ return surface;
+}
+
+static void wine_vk_surface_release(struct wine_vk_surface *surface)
+{
+ if (InterlockedDecrement(&surface->ref))
return;
- /* vkDestroySurfaceKHR must handle VK_NULL_HANDLE (0) for surface. */
- pvkDestroySurfaceKHR(instance, surface->surface, NULL /* allocator */);
-
if (surface->window)
XDestroyWindow(gdi_display, surface->window);
heap_free(surface);
}
+void wine_vk_surface_destroy(HWND hwnd)
+{
+ struct wine_vk_surface *surface;
+ EnterCriticalSection(&context_section);
+ if (!XFindContext(gdi_display, (XID)hwnd, vulkan_hwnd_context, (char **)&surface))
+ {
+ wine_vk_surface_release(surface);
+ }
+ XDeleteContext(gdi_display, (XID)hwnd, vulkan_hwnd_context);
+ LeaveCriticalSection(&context_section);
+}
+
static VkResult X11DRV_vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *index)
{
@@ -245,7 +274,7 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
{
VkResult res;
VkXlibSurfaceCreateInfoKHR create_info_host;
- struct wine_vk_surface *x11_surface;
+ struct wine_vk_surface *x11_surface, *prev;
TRACE("%p %p %p %p\n", instance, create_info, allocator, surface);
@@ -263,6 +292,8 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
if (!x11_surface)
return VK_ERROR_OUT_OF_HOST_MEMORY;
+ x11_surface->ref = 1;
+
x11_surface->window = create_client_window(create_info->hwnd, &default_visual);
if (!x11_surface->window)
{
@@ -286,13 +317,21 @@ static VkResult X11DRV_vkCreateWin32SurfaceKHR(VkInstance instance,
goto err;
}
+ EnterCriticalSection(&context_section);
+ if (!XFindContext(gdi_display, (XID)create_info->hwnd, vulkan_hwnd_context, (char **)&prev))
+ {
+ wine_vk_surface_release(prev);
+ }
+ XSaveContext(gdi_display, (XID)create_info->hwnd, vulkan_hwnd_context, (char *)wine_vk_surface_grab(x11_surface));
+ LeaveCriticalSection(&context_section);
+
*surface = (uintptr_t)x11_surface;
TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*surface));
return VK_SUCCESS;
err:
- wine_vk_surface_destroy(instance, x11_surface);
+ wine_vk_surface_release(x11_surface);
return res;
}
@@ -316,7 +355,13 @@ static void X11DRV_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface
if (allocator)
FIXME("Support for allocation callbacks not implemented yet\n");
- wine_vk_surface_destroy(instance, x11_surface);
+ /* vkDestroySurfaceKHR must handle VK_NULL_HANDLE (0) for surface. */
+ if (x11_surface)
+ {
+ pvkDestroySurfaceKHR(instance, x11_surface->surface, NULL /* allocator */);
+
+ wine_vk_surface_release(x11_surface);
+ }
}
static void X11DRV_vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 5fecd9a17b..a848dc61e1 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -1719,6 +1719,7 @@ void CDECL X11DRV_DestroyWindow( HWND hwnd )
release_win_data( data );
HeapFree( GetProcessHeap(), 0, data );
destroy_gl_drawable( hwnd );
+ wine_vk_surface_destroy( hwnd );
}
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 85a05a904a..939c2e7f3b 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -586,6 +586,7 @@ extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
extern void sync_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN;
extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
+extern void wine_vk_surface_destroy( HWND hwnd ) DECLSPEC_HIDDEN;
extern void wait_for_withdrawn_state( HWND hwnd, BOOL set ) DECLSPEC_HIDDEN;
extern Window init_clip_window(void) DECLSPEC_HIDDEN;
--
2.17.1
June 13, 2018
Re: [PATCH 1/2] winmm/tests: Avoid and ARRAY_SIZE-like macro
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39112
Your paranoid android.
=== w8 (32 bit mmio) ===
TestBot process got stuck or died unexpectedly
The previous 1 run(s) terminated abnormally
June 13, 2018
Re: [PATCH 1/2] dsound/tests: Avoid ARRAY_SIZE-like macros
by Michael Stefaniuc
On 06/13/2018 08:54 PM, Marvin wrote:
> While running your changed tests on Windows, I think I found new failures.
> Being a bot and all I'm not very good at pattern recognition, so I might be
> wrong, but could you please double-check?
> Full results can be found at
> https://testbot.winehq.org/JobDetails.pl?Key=39109
>
> Your paranoid android.
>
>
> === w8 (32 bit ds3d8) ===
> TestBot process got stuck or died unexpectedly
> The previous 1 run(s) terminated abnormally
Testbot issue, looks like the start time is missing:
0e90:ds3d8: 757 tests executed (0 marked as todo, 0 failures), 0 skipped.
dsound:ds3d8:0e90 done (0) in 0s
bye
michael
June 13, 2018
Re: [PATCH 1/2] dsound/tests: Avoid ARRAY_SIZE-like macros
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39109
Your paranoid android.
=== w8 (32 bit ds3d8) ===
TestBot process got stuck or died unexpectedly
The previous 1 run(s) terminated abnormally
June 13, 2018
Re: [PATCH 6/6] dxgi: Get supported feature levels from wined3d caps.
by Matteo Bruni
2018-06-13 12:24 GMT+02:00 Józef Kucia <jkucia(a)codeweavers.com>:
> On a side note, handling of feature levels 9_x appears to be incorrect
> (AFAIK feature levels 9_x always use SM2 shaders).
True, but it's complicated...
Looking around https://msdn.microsoft.com/en-us/library/windows/desktop/ff476876(v=vs.85).…
you can see that feature level 9_3 e.g. mandates support for max
texture size >= 4096, which is only guaranteed by SM3-level hardware
(https://msdn.microsoft.com/en-us/library/windows/desktop/bb219845(v=vs.85).…)
IIRC there were a few of those, which is why I decided to require SM3
for 9_3 even though the shaders themselves are going to be SM2 only.
June 13, 2018
[PATCH 2/2] winmm/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/winmm/tests/joystick.c | 4 ++--
dlls/winmm/tests/midi.c | 2 +-
dlls/winmm/tests/mmio.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/winmm/tests/joystick.c b/dlls/winmm/tests/joystick.c
index 5714001315..7531bd6481 100644
--- a/dlls/winmm/tests/joystick.c
+++ b/dlls/winmm/tests/joystick.c
@@ -139,7 +139,7 @@ static void test_api(void)
/* Try some unusual period values for joySetCapture and unusual threshold values for joySetThreshold.
* Windows XP allows almost all test values, Windows 8 will return error on most test values, Windows
* 98 allows anything but cuts the values to their maximum supported values internally. */
- for (i = 0; i < sizeof(period) / sizeof(period[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(period); i++)
{
ret = joySetCapture(window, joyid, period[i], FALSE);
if (win8 && ((1 << i) & period_win8_error))
@@ -190,7 +190,7 @@ static void test_api(void)
ok(ret == JOYERR_NOERROR, "Expected %d, got %d\n", JOYERR_NOERROR, ret);
infoex.ex.dwSize = sizeof(infoex.ex);
- for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(flags); i++)
{
infoex.ex.dwFlags = flags[i];
ret = joyGetPosEx(joyid, &infoex.ex);
diff --git a/dlls/winmm/tests/midi.c b/dlls/winmm/tests/midi.c
index fe3cc5c876..3b8bd2287d 100644
--- a/dlls/winmm/tests/midi.c
+++ b/dlls/winmm/tests/midi.c
@@ -549,7 +549,7 @@ static void CALLBACK time_stamp_callback(HMIDIOUT hmo, UINT msg, DWORD_PTR insta
struct time_stamp_records *records = (struct time_stamp_records *)instance;
switch (msg) {
case MM_MOM_POSITIONCB:
- if (records->count < sizeof(records->time_stamp)/sizeof(records->time_stamp[0]))
+ if (records->count < ARRAY_SIZE(records->time_stamp))
records->time_stamp[records->count] = GetTickCount();
records->count++;
break;
diff --git a/dlls/winmm/tests/mmio.c b/dlls/winmm/tests/mmio.c
index 48367ee6d9..5501c319c5 100644
--- a/dlls/winmm/tests/mmio.c
+++ b/dlls/winmm/tests/mmio.c
@@ -606,7 +606,7 @@ static LRESULT CALLBACK mmio_test_IOProc(LPSTR lpMMIOInfo, UINT uMessage, LPARAM
case MMIOM_OPEN:
if (lpInfo->fccIOProc == FOURCC_DOS)
lpInfo->fccIOProc = mmioFOURCC('F', 'A', 'I', 'L');
- for (i = 0; i < sizeof(lpInfo->adwInfo) / sizeof(*lpInfo->adwInfo); i++)
+ for (i = 0; i < ARRAY_SIZE(lpInfo->adwInfo); i++)
ok(lpInfo->adwInfo[i] == 0, "[%d] Expected 0, got %u\n", i, lpInfo->adwInfo[i]);
return MMSYSERR_NOERROR;
case MMIOM_CLOSE:
--
2.14.4
June 13, 2018
[PATCH 1/2] winmm/tests: Avoid and ARRAY_SIZE-like macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/winmm/tests/capture.c | 2 +-
dlls/winmm/tests/wave.c | 2 +-
dlls/winmm/tests/winmm_test.h | 1 -
3 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/winmm/tests/capture.c b/dlls/winmm/tests/capture.c
index fd4005cdab..ba71f9ca80 100644
--- a/dlls/winmm/tests/capture.c
+++ b/dlls/winmm/tests/capture.c
@@ -398,7 +398,7 @@ static void wave_in_test_device(UINT_PTR device)
HeapFree(GetProcessHeap(), 0, nameA);
- for (f=0;f<NB_WIN_FORMATS;f++) {
+ for (f = 0; f < ARRAY_SIZE(win_formats); f++) {
format.wFormatTag=WAVE_FORMAT_PCM;
format.nChannels=win_formats[f][3];
format.wBitsPerSample=win_formats[f][2];
diff --git a/dlls/winmm/tests/wave.c b/dlls/winmm/tests/wave.c
index 8d7dfd6b68..b402e21917 100644
--- a/dlls/winmm/tests/wave.c
+++ b/dlls/winmm/tests/wave.c
@@ -1041,7 +1041,7 @@ static void wave_out_test_device(UINT_PTR device)
CALLBACK_EVENT,&capsA,TRUE,FALSE,FALSE);
}
- for (f=0;f<NB_WIN_FORMATS;f++) {
+ for (f = 0; f < ARRAY_SIZE(win_formats); f++) {
format.wFormatTag=WAVE_FORMAT_PCM;
format.nChannels=win_formats[f][3];
format.wBitsPerSample=win_formats[f][2];
diff --git a/dlls/winmm/tests/winmm_test.h b/dlls/winmm/tests/winmm_test.h
index 177dc2e837..d5fb70afbd 100644
--- a/dlls/winmm/tests/winmm_test.h
+++ b/dlls/winmm/tests/winmm_test.h
@@ -68,7 +68,6 @@ static const unsigned int win_formats[][4] = {
{WAVE_FORMAT_96M16, 96000, 16, 1},
{WAVE_FORMAT_96S16, 96000, 16, 2}
};
-#define NB_WIN_FORMATS (sizeof(win_formats)/sizeof(*win_formats))
extern const char* dev_name(int);
extern const char* wave_open_flags(DWORD);
--
2.14.4
June 13, 2018
[PATCH] ole32/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ole32/tests/compobj.c | 6 +++---
dlls/ole32/tests/dragdrop.c | 2 +-
dlls/ole32/tests/marshal.c | 4 ++--
dlls/ole32/tests/moniker.c | 19 ++++++++++---------
dlls/ole32/tests/ole2.c | 8 ++++----
dlls/ole32/tests/ole_server.c | 2 +-
dlls/ole32/tests/propvariant.c | 2 +-
dlls/ole32/tests/storage32.c | 6 +++---
8 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index c43e86c605..352cfbf4e9 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -197,7 +197,7 @@ static BOOL create_manifest_file(const char *filename, const char *manifest)
WCHAR path[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
- GetFullPathNameW(path, sizeof(manifest_path)/sizeof(WCHAR), manifest_path, NULL);
+ GetFullPathNameW(path, ARRAY_SIZE(manifest_path), manifest_path, NULL);
manifest_len = strlen(manifest);
file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
@@ -2334,7 +2334,7 @@ static void test_OleRegGetUserType(void)
}
/* test using registered CLSID */
- StringFromGUID2(&CLSID_non_existent, clsidW, sizeof(clsidW)/sizeof(clsidW[0]));
+ StringFromGUID2(&CLSID_non_existent, clsidW, ARRAY_SIZE(clsidW));
ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsidkeyW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &clsidhkey, &disposition);
if (!ret)
@@ -2522,7 +2522,7 @@ static void flush_messages(void)
static LRESULT CALLBACK cowait_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
- if(cowait_msgs_last < sizeof(cowait_msgs)/sizeof(*cowait_msgs))
+ if(cowait_msgs_last < ARRAY_SIZE(cowait_msgs))
cowait_msgs[cowait_msgs_last++] = msg;
if(msg == WM_DDE_FIRST)
return 6;
diff --git a/dlls/ole32/tests/dragdrop.c b/dlls/ole32/tests/dragdrop.c
index 09112b8f0d..77e47d723d 100644
--- a/dlls/ole32/tests/dragdrop.c
+++ b/dlls/ole32/tests/dragdrop.c
@@ -701,7 +701,7 @@ static void test_DoDragDrop(void)
GetWindowRect(hwnd, &rect);
ok(SetCursorPos(rect.left+50, rect.top+50), "SetCursorPos failed\n");
- for (seq = 0; seq < sizeof(call_lists) / sizeof(call_lists[0]); seq++)
+ for (seq = 0; seq < ARRAY_SIZE(call_lists); seq++)
{
DWORD effect_in;
trace("%d\n", seq);
diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c
index 39867394fb..c1d53942da 100644
--- a/dlls/ole32/tests/marshal.c
+++ b/dlls/ole32/tests/marshal.c
@@ -3941,8 +3941,8 @@ static const char *debugstr_iid(REFIID riid)
WCHAR bufferW[39];
char buffer[39];
LONG name_size = sizeof(name);
- StringFromGUID2(riid, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
- WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
+ StringFromGUID2(riid, bufferW, ARRAY_SIZE(bufferW));
+ WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer, sizeof(buffer), NULL, NULL);
if (RegOpenKeyExA(HKEY_CLASSES_ROOT, "Interface", 0, KEY_QUERY_VALUE, &hkeyInterface) != ERROR_SUCCESS)
{
memcpy(name, buffer, sizeof(buffer));
diff --git a/dlls/ole32/tests/moniker.c b/dlls/ole32/tests/moniker.c
index 7b67dfdb95..7302ab0f21 100644
--- a/dlls/ole32/tests/moniker.c
+++ b/dlls/ole32/tests/moniker.c
@@ -38,7 +38,6 @@
#define ok_more_than_one_lock() ok(cLocks > 0, "Number of locks should be > 0, but actually is %d\n", cLocks)
#define ok_no_locks() ok(cLocks == 0, "Number of locks should be 0, but actually is %d\n", cLocks)
#define ok_ole_success(hr, func) ok(hr == S_OK, #func " failed with error 0x%08x\n", hr)
-#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
#define CHECK_EXPECTED_METHOD(method_name) \
do { \
@@ -905,7 +904,7 @@ static void test_MkParseDisplayName(void)
hr = CreateBindCtx(0, &pbc);
ok_ole_success(hr, CreateBindCtx);
- for (i = 0; i < sizeof(invalid_parameters)/sizeof(invalid_parameters[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(invalid_parameters); i++)
{
eaten = 0xdeadbeef;
pmk = (IMoniker *)0xdeadbeef;
@@ -947,7 +946,7 @@ static void test_MkParseDisplayName(void)
pmk = NULL;
hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
- ok(eaten == sizeof(wszDisplayName)/sizeof(WCHAR) - 1,
+ ok(eaten == ARRAY_SIZE(wszDisplayName) - 1,
"Processed character count should have been 43 instead of %u\n", eaten);
if (pmk)
{
@@ -969,7 +968,7 @@ static void test_MkParseDisplayName(void)
pmk = NULL;
hr = MkParseDisplayName(pbc, wszDisplayNameRunning, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
- ok(eaten == sizeof(wszDisplayNameRunning)/sizeof(WCHAR) - 1,
+ ok(eaten == ARRAY_SIZE(wszDisplayNameRunning) - 1,
"Processed character count should have been 15 instead of %u\n", eaten);
if (pmk)
{
@@ -987,7 +986,7 @@ static void test_MkParseDisplayName(void)
expected_display_name = wszDisplayNameProgId1;
hr = MkParseDisplayName(pbc, wszDisplayNameProgId1, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
- ok(eaten == sizeof(wszDisplayNameProgId1)/sizeof(WCHAR) - 1,
+ ok(eaten == ARRAY_SIZE(wszDisplayNameProgId1) - 1,
"Processed character count should have been 8 instead of %u\n", eaten);
if (pmk)
{
@@ -999,7 +998,7 @@ static void test_MkParseDisplayName(void)
expected_display_name = wszDisplayNameProgId2;
hr = MkParseDisplayName(pbc, wszDisplayNameProgId2, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
- ok(eaten == sizeof(wszDisplayNameProgId2)/sizeof(WCHAR) - 1,
+ ok(eaten == ARRAY_SIZE(wszDisplayNameProgId2) - 1,
"Processed character count should have been 8 instead of %u\n", eaten);
if (pmk)
{
@@ -1021,7 +1020,8 @@ static void test_MkParseDisplayName(void)
GetSystemDirectoryA(szDisplayNameFile, sizeof(szDisplayNameFile));
strcat(szDisplayNameFile, "\\kernel32.dll");
- len = MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile, sizeof(wszDisplayNameFile)/sizeof(wszDisplayNameFile[0]));
+ len = MultiByteToWideChar(CP_ACP, 0, szDisplayNameFile, -1, wszDisplayNameFile,
+ ARRAY_SIZE(wszDisplayNameFile));
hr = MkParseDisplayName(pbc, wszDisplayNameFile, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
ok(eaten == len - 1, "Processed character count should have been %d instead of %u\n", len - 1, eaten);
@@ -1034,7 +1034,8 @@ static void test_MkParseDisplayName(void)
hr = MkParseDisplayName(pbc, wszDisplayName, &eaten, &pmk);
ok_ole_success(hr, MkParseDisplayName);
- ok(eaten == sizeof(wszDisplayName)/sizeof(WCHAR) - 1, "Processed character count should have been 43 instead of %u\n", eaten);
+ ok(eaten == ARRAY_SIZE(wszDisplayName) - 1,
+ "Processed character count should have been 43 instead of %u\n", eaten);
if (pmk)
{
@@ -1550,7 +1551,7 @@ static void test_file_monikers(void)
trace("ACP is %u\n", GetACP());
- for (i = 0; i < COUNTOF(wszFile); ++i)
+ for (i = 0; i < ARRAY_SIZE(wszFile); ++i)
{
int j ;
if (i == 2)
diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c
index 74dadd4048..48c9e0cbab 100644
--- a/dlls/ole32/tests/ole2.c
+++ b/dlls/ole32/tests/ole2.c
@@ -1728,7 +1728,7 @@ static void test_data_cache(void)
{ NULL, 0 }
};
- GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]));
+ GetSystemDirectoryA(szSystemDir, ARRAY_SIZE(szSystemDir));
expected_method_list = methods_cacheinitnew;
@@ -1860,7 +1860,7 @@ static void test_data_cache(void)
hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection);
ok_ole_success(hr, "IOleCache_Cache");
- MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0]));
+ MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, ARRAY_SIZE(wszPath));
memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32));
fmtetc.cfFormat = CF_METAFILEPICT;
@@ -2490,7 +2490,7 @@ static void test_data_cache_init(void)
{ &CLSID_Picture_EnhMetafile, 3, 1 }
};
- for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(data); i++)
{
hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache );
ok( hr == S_OK, "got %08x\n", hr );
@@ -4541,7 +4541,7 @@ static void test_data_cache_contents(void)
{ &stg_def_9, &stg_def_9_saved },
};
- for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_data); i++)
{
if (winetest_debug > 1)
trace("start testing storage def %d\n", i);
diff --git a/dlls/ole32/tests/ole_server.c b/dlls/ole32/tests/ole_server.c
index 77abda47aa..f5c845de26 100644
--- a/dlls/ole32/tests/ole_server.c
+++ b/dlls/ole32/tests/ole_server.c
@@ -69,7 +69,7 @@ static const char *debugstr_guid(const GUID *guid)
if (!guid) return "(null)";
- for (i = 0; i < sizeof(guid_name)/sizeof(guid_name[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(guid_name); i++)
{
if (IsEqualIID(guid, guid_name[i].guid))
return guid_name[i].name;
diff --git a/dlls/ole32/tests/propvariant.c b/dlls/ole32/tests/propvariant.c
index ade45fbd42..97c4eec4ca 100644
--- a/dlls/ole32/tests/propvariant.c
+++ b/dlls/ole32/tests/propvariant.c
@@ -189,7 +189,7 @@ static void test_validtypes(void)
ok(U(propvar).uhVal.QuadPart == 0, "expected 0, got %#x/%#x\n",
U(propvar).uhVal.u.LowPart, U(propvar).uhVal.u.HighPart);
- for (i = 0; i < sizeof(valid_types)/sizeof(valid_types[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(valid_types); i++)
{
VARTYPE vt;
diff --git a/dlls/ole32/tests/storage32.c b/dlls/ole32/tests/storage32.c
index 43c0c28ad5..9d2c970e86 100644
--- a/dlls/ole32/tests/storage32.c
+++ b/dlls/ole32/tests/storage32.c
@@ -2084,9 +2084,9 @@ static void _test_file_access(LPCSTR file, const struct access_res *ares, DWORD
{
int i, j, idx = 0;
- for (i = 0; i < sizeof(access_modes)/sizeof(access_modes[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(access_modes); i++)
{
- for (j = 0; j < sizeof(share_modes)/sizeof(share_modes[0]); j++)
+ for (j = 0; j < ARRAY_SIZE(share_modes); j++)
{
DWORD lasterr;
HANDLE hfile;
@@ -3490,7 +3490,7 @@ static void test_locking(void)
IStorage *stg;
HRESULT hr;
- for (i=0; i<sizeof(lock_tests)/sizeof(lock_tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(lock_tests); i++)
{
const struct lock_test *current = &lock_tests[i];
BOOL any_failure = FALSE;
--
2.14.4
June 13, 2018
[PATCH 2/2] dsound/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/dsound/tests/ds3d.c | 2 +-
dlls/dsound/tests/dsound.c | 15 ++++++---------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/dlls/dsound/tests/ds3d.c b/dlls/dsound/tests/ds3d.c
index d4356c2b6c..1b44afff8d 100644
--- a/dlls/dsound/tests/ds3d.c
+++ b/dlls/dsound/tests/ds3d.c
@@ -139,7 +139,7 @@ const char * getDSBCAPS(DWORD xmask) {
buffer[0] = 0;
- for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
+ for (i = 0; i < ARRAY_SIZE(flags); i++) {
if ((flags[i].mask & xmask) == flags[i].mask) {
if (first)
first = FALSE;
diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c
index 375abc8761..0807d43788 100644
--- a/dlls/dsound/tests/dsound.c
+++ b/dlls/dsound/tests/dsound.c
@@ -1004,8 +1004,8 @@ static HRESULT test_frequency(LPGUID lpGuid)
if (rc!=DS_OK)
goto EXIT1;
- for (f=0;f<sizeof(fmts)/sizeof(fmts[0]);f++) {
- for (r=0;r<sizeof(rates)/sizeof(rates[0]);r++) {
+ for (f = 0; f < ARRAY_SIZE(fmts); f++) {
+ for (r = 0; r < ARRAY_SIZE(rates); r++) {
init_format(&wfx,WAVE_FORMAT_PCM,11025,fmts[f].bits,
fmts[f].channels);
secondary=NULL;
@@ -1135,7 +1135,7 @@ static HRESULT test_duplicate(LPGUID lpGuid)
int i;
/* Prepare notify events */
- for (i=0;i<sizeof(event)/sizeof(event[0]);i++) {
+ for (i = 0; i < ARRAY_SIZE(event); i++) {
event[i] = CreateEventW(NULL, FALSE, FALSE, NULL);
}
@@ -1174,8 +1174,7 @@ static HRESULT test_duplicate(LPGUID lpGuid)
"IDirectSound_DuplicateSoundBuffer failed %08x\n",rc);
trace("testing duplicated buffer without notifications.\n");
- test_notify(duplicated,sizeof(event)/sizeof(event[0]),
- event,WAIT_TIMEOUT);
+ test_notify(duplicated, ARRAY_SIZE(event), event, WAIT_TIMEOUT);
rc=IDirectSoundBuffer_QueryInterface(duplicated,
&IID_IDirectSoundNotify,
@@ -1192,8 +1191,7 @@ static HRESULT test_duplicate(LPGUID lpGuid)
"failed %08x\n",rc);
trace("testing duplicated buffer with a notification.\n");
- test_notify(duplicated,sizeof(event)/sizeof(event[0]),
- event,WAIT_OBJECT_0+1);
+ test_notify(duplicated, ARRAY_SIZE(event), event, WAIT_OBJECT_0 + 1);
ref=IDirectSoundNotify_Release(dup_notify);
ok(ref==0,"IDirectSoundNotify_Release() has %d references, "
@@ -1204,8 +1202,7 @@ static HRESULT test_duplicate(LPGUID lpGuid)
"should have 0\n",ref);
trace("testing original buffer with a notification.\n");
- test_notify(original,sizeof(event)/sizeof(event[0]),
- event,WAIT_OBJECT_0);
+ test_notify(original, ARRAY_SIZE(event), event, WAIT_OBJECT_0);
ref=IDirectSoundBuffer_Release(duplicated);
ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
--
2.14.4
June 13, 2018
[PATCH 1/2] dsound/tests: Avoid ARRAY_SIZE-like macros
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/dsound/tests/capture.c | 2 +-
dlls/dsound/tests/dsound.c | 8 ++++----
dlls/dsound/tests/dsound8.c | 8 ++++----
dlls/dsound/tests/dsound_test.h | 2 --
4 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/dlls/dsound/tests/capture.c b/dlls/dsound/tests/capture.c
index a23d1eb6f6..dada067956 100644
--- a/dlls/dsound/tests/capture.c
+++ b/dlls/dsound/tests/capture.c
@@ -549,7 +549,7 @@ static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
"should have 0\n",ref);
}
- for (f=0;f<NB_FORMATS;f++) {
+ for (f = 0; f < ARRAY_SIZE(formats); f++) {
dscbo=NULL;
init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
formats[f][2]);
diff --git a/dlls/dsound/tests/dsound.c b/dlls/dsound/tests/dsound.c
index 07c8908add..375abc8761 100644
--- a/dlls/dsound/tests/dsound.c
+++ b/dlls/dsound/tests/dsound.c
@@ -571,8 +571,8 @@ static HRESULT test_primary_secondary(LPGUID lpGuid)
"IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc);
if (rc==DS_OK && primary!=NULL) {
- for (f=0;f<NB_FORMATS;f++) {
- for (tag=0;tag<NB_TAGS;tag++) {
+ for (f = 0; f < ARRAY_SIZE(formats); f++) {
+ for (tag = 0; tag < ARRAY_SIZE(format_tags); tag++) {
/* if float, we only want to test 32-bit */
if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
continue;
@@ -718,8 +718,8 @@ static HRESULT test_secondary(LPGUID lpGuid)
if (rc!=DS_OK)
goto EXIT1;
- for (f=0;f<NB_FORMATS;f++) {
- for (tag=0;tag<NB_TAGS;tag++) {
+ for (f = 0; f < ARRAY_SIZE(formats); f++) {
+ for (tag = 0; tag < ARRAY_SIZE(format_tags); tag++) {
WAVEFORMATEXTENSIBLE wfxe;
/* if float, we only want to test 32-bit */
diff --git a/dlls/dsound/tests/dsound8.c b/dlls/dsound/tests/dsound8.c
index a6e3f12ae3..fabd8a037e 100644
--- a/dlls/dsound/tests/dsound8.c
+++ b/dlls/dsound/tests/dsound8.c
@@ -581,8 +581,8 @@ static HRESULT test_primary_secondary8(LPGUID lpGuid)
"%08x\n",rc);
if (rc==DS_OK && primary!=NULL) {
- for (f=0;f<NB_FORMATS;f++) {
- for (tag=0;tag<NB_TAGS;tag++) {
+ for (f = 0; f < ARRAY_SIZE(formats); f++) {
+ for (tag = 0; tag < ARRAY_SIZE(format_tags); tag++) {
/* if float, we only want to test 32-bit */
if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32))
continue;
@@ -727,8 +727,8 @@ static HRESULT test_secondary8(LPGUID lpGuid)
if (rc!=DS_OK)
goto EXIT1;
- for (f=0;f<NB_FORMATS;f++) {
- for (tag=0;tag<NB_TAGS;tag++) {
+ for (f = 0; f < ARRAY_SIZE(formats); f++) {
+ for (tag = 0; tag < ARRAY_SIZE(format_tags); tag++) {
WAVEFORMATEXTENSIBLE wfxe;
/* if float, we only want to test 32-bit */
diff --git a/dlls/dsound/tests/dsound_test.h b/dlls/dsound/tests/dsound_test.h
index 8a8f2498d0..04f995e359 100644
--- a/dlls/dsound/tests/dsound_test.h
+++ b/dlls/dsound/tests/dsound_test.h
@@ -71,10 +71,8 @@ static const unsigned int formats[][4]={
{96000, 32, 1, 0 },
{96000, 32, 2, 0 }
};
-#define NB_FORMATS (sizeof(formats)/sizeof(*formats))
static const unsigned int format_tags[] = {WAVE_FORMAT_PCM, WAVE_FORMAT_IEEE_FLOAT};
-#define NB_TAGS (sizeof(format_tags)/sizeof(*format_tags))
/* The time slice determines how often we will service the buffer */
#define TIME_SLICE 31
--
2.14.4
June 13, 2018