Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c4548c04
Commit
c4548c04
authored
Dec 08, 2021
by
Eric Pouech
Committed by
Alexandre Julliard
Dec 10, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedbg: Add helper to compare types and use it to detect wrong assigments.
Signed-off-by:
Eric Pouech
<
eric.pouech@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
e60fdbf1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
186 additions
and
6 deletions
+186
-6
debugger.h
programs/winedbg/debugger.h
+2
-0
types.c
programs/winedbg/types.c
+184
-6
No files found.
programs/winedbg/debugger.h
View file @
c4548c04
...
...
@@ -493,6 +493,8 @@ extern BOOL types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_T
extern
BOOL
types_get_real_type
(
struct
dbg_type
*
type
,
DWORD
*
tag
);
extern
struct
dbg_type
types_find_pointer
(
const
struct
dbg_type
*
type
);
extern
struct
dbg_type
types_find_type
(
DWORD64
linear
,
const
char
*
name
,
enum
SymTagEnum
tag
);
extern
BOOL
types_compare
(
const
struct
dbg_type
,
const
struct
dbg_type
,
BOOL
*
equal
);
extern
BOOL
types_is_integral_type
(
const
struct
dbg_lvalue
*
);
/* winedbg.c */
extern
void
dbg_outputW
(
const
WCHAR
*
buffer
,
int
len
);
...
...
programs/winedbg/types.c
View file @
c4548c04
...
...
@@ -164,16 +164,33 @@ BOOL types_store_value(struct dbg_lvalue* lvalue_to, const struct dbg_lvalue* lv
{
dbg_lgint_t
val
;
DWORD64
size
;
BOOL
equal
;
if
(
!
types_get_info
(
&
lvalue_to
->
type
,
TI_GET_LENGTH
,
&
size
))
return
FALSE
;
if
(
sizeof
(
val
)
<
size
)
if
(
!
lvalue_to
->
bitlen
&&
!
lvalue_from
->
bitlen
)
{
dbg_printf
(
"Insufficient size
\n
"
);
return
FALSE
;
if
(
!
types_compare
(
lvalue_to
->
type
,
lvalue_from
->
type
,
&
equal
))
return
FALSE
;
if
(
equal
)
{
if
(
!
types_get_info
(
&
lvalue_to
->
type
,
TI_GET_LENGTH
,
&
size
))
return
FALSE
;
if
(
sizeof
(
val
)
<
size
)
{
return
memory_read_value
(
lvalue_from
,
size
,
&
val
)
&&
memory_write_value
(
lvalue_to
,
size
,
&
val
);
}
dbg_printf
(
"NIY
\n
"
);
/* else: should allocate intermediate buffer... */
return
FALSE
;
}
}
if
(
types_is_integral_type
(
lvalue_from
)
&&
types_is_integral_type
(
lvalue_to
))
{
/* doing integer conversion (about sign, size) */
val
=
types_extract_as_integer
(
lvalue_from
);
return
memory_store_integer
(
lvalue_to
,
val
);
}
/* FIXME: should support floats as well */
val
=
types_extract_as_integer
(
lvalue_from
)
;
return
memory_store_integer
(
lvalue_to
,
val
)
;
dbg_printf
(
"Cannot assign (different types)
\n
"
);
return
FALSE
;
return
FALSE
;
}
/******************************************************************
...
...
@@ -910,3 +927,164 @@ BOOL types_get_info(const struct dbg_type* type, IMAGEHLP_SYMBOL_TYPE_INFO ti, v
#undef X
return
TRUE
;
}
static
BOOL
types_compare_name
(
struct
dbg_type
type1
,
struct
dbg_type
type2
,
BOOL
*
equal
)
{
LPWSTR
name1
,
name2
;
BOOL
ret
;
if
(
types_get_info
(
&
type1
,
TI_GET_SYMNAME
,
&
name1
))
{
if
(
types_get_info
(
&
type2
,
TI_GET_SYMNAME
,
&
name2
))
{
*
equal
=
!
wcscmp
(
name1
,
name2
);
ret
=
TRUE
;
HeapFree
(
GetProcessHeap
(),
0
,
name2
);
}
else
ret
=
FALSE
;
HeapFree
(
GetProcessHeap
(),
0
,
name1
);
}
else
ret
=
FALSE
;
return
ret
;
}
static
BOOL
types_compare_children
(
struct
dbg_type
type1
,
struct
dbg_type
type2
,
BOOL
*
equal
,
DWORD
tag
)
{
DWORD
count1
,
count2
,
i
;
DWORD
*
children
;
BOOL
ret
;
if
(
!
types_get_info
(
&
type1
,
TI_GET_CHILDRENCOUNT
,
&
count1
)
||
!
types_get_info
(
&
type2
,
TI_GET_CHILDRENCOUNT
,
&
count2
))
return
FALSE
;
if
(
count1
!=
count2
)
{
*
equal
=
FALSE
;
return
TRUE
;}
if
(
!
count1
)
return
*
equal
=
TRUE
;
if
((
children
=
malloc
(
sizeof
(
*
children
)
*
2
*
count1
))
==
NULL
)
return
FALSE
;
if
(
types_get_info
(
&
type1
,
TI_FINDCHILDREN
,
&
children
[
0
])
&&
types_get_info
(
&
type2
,
TI_FINDCHILDREN
,
&
children
[
count1
]))
{
for
(
i
=
0
;
i
<
count1
;
++
i
)
{
type1
.
id
=
children
[
i
];
type2
.
id
=
children
[
count1
+
i
];
switch
(
tag
)
{
case
SymTagFunctionType
:
ret
=
types_compare
(
type1
,
type2
,
equal
);
break
;
case
SymTagUDT
:
/* each child is a SymTagData that describes the member */
ret
=
types_compare_name
(
type1
,
type2
,
equal
);
if
(
ret
&&
*
equal
)
{
/* compare type of member */
ret
=
types_get_info
(
&
type1
,
TI_GET_TYPE
,
&
type1
.
id
)
&&
types_get_info
(
&
type2
,
TI_GET_TYPE
,
&
type2
.
id
);
if
(
ret
)
ret
=
types_compare
(
type1
,
type2
,
equal
);
/* FIXME should compare bitfield info when present */
}
break
;
default:
ret
=
FALSE
;
break
;
}
if
(
!
ret
||
!*
equal
)
break
;
}
if
(
i
==
count1
)
ret
=
*
equal
=
TRUE
;
}
else
ret
=
FALSE
;
free
(
children
);
return
ret
;
}
BOOL
types_compare
(
struct
dbg_type
type1
,
struct
dbg_type
type2
,
BOOL
*
equal
)
{
DWORD
tag1
,
tag2
;
DWORD64
size1
,
size2
;
DWORD
bt1
,
bt2
;
DWORD
count1
,
count2
;
BOOL
ret
;
do
{
if
(
type1
.
module
==
type2
.
module
&&
type1
.
id
==
type2
.
id
)
return
*
equal
=
TRUE
;
if
(
!
types_get_real_type
(
&
type1
,
&
tag1
)
||
!
types_get_real_type
(
&
type2
,
&
tag2
))
return
FALSE
;
if
(
type1
.
module
==
type2
.
module
&&
type1
.
id
==
type2
.
id
)
return
*
equal
=
TRUE
;
if
(
tag1
!=
tag2
)
return
!
(
*
equal
=
FALSE
);
switch
(
tag1
)
{
case
SymTagBaseType
:
if
(
!
types_get_info
(
&
type1
,
TI_GET_BASETYPE
,
&
bt1
)
||
!
types_get_info
(
&
type2
,
TI_GET_BASETYPE
,
&
bt2
)
||
!
types_get_info
(
&
type1
,
TI_GET_LENGTH
,
&
size1
)
||
!
types_get_info
(
&
type2
,
TI_GET_LENGTH
,
&
size2
))
return
FALSE
;
*
equal
=
bt1
==
bt2
&&
size1
==
size2
;
return
TRUE
;
case
SymTagPointerType
:
/* compare sub types */
break
;
case
SymTagUDT
:
case
SymTagEnum
:
ret
=
types_compare_name
(
type1
,
type2
,
equal
);
if
(
!
ret
||
!*
equal
)
return
ret
;
ret
=
types_compare_children
(
type1
,
type2
,
equal
,
tag1
);
if
(
!
ret
||
!*
equal
)
return
ret
;
if
(
tag1
==
SymTagUDT
)
return
TRUE
;
/* compare underlying type for enums */
break
;
case
SymTagArrayType
:
if
(
!
types_get_info
(
&
type1
,
TI_GET_LENGTH
,
&
size1
)
||
!
types_get_info
(
&
type2
,
TI_GET_LENGTH
,
&
size2
)
||
!
types_get_info
(
&
type1
,
TI_GET_COUNT
,
&
count1
)
||
!
types_get_info
(
&
type2
,
TI_GET_COUNT
,
&
count2
))
return
FALSE
;
if
(
size1
==
size2
&&
count1
==
count2
)
{
struct
dbg_type
subtype1
=
type1
,
subtype2
=
type2
;
if
(
!
types_get_info
(
&
type1
,
TI_GET_ARRAYINDEXTYPEID
,
&
subtype1
.
id
)
||
!
types_get_info
(
&
type2
,
TI_GET_ARRAYINDEXTYPEID
,
&
subtype2
.
id
))
return
FALSE
;
if
(
!
types_compare
(
subtype1
,
subtype2
,
equal
))
return
FALSE
;
if
(
!*
equal
)
return
TRUE
;
}
else
return
!
(
*
equal
=
FALSE
);
/* compare subtypes */
break
;
case
SymTagFunctionType
:
if
(
!
types_compare_children
(
type1
,
type2
,
equal
,
tag1
))
return
FALSE
;
if
(
!*
equal
)
return
TRUE
;
/* compare return:ed type */
break
;
case
SymTagFunctionArgType
:
/* compare argument type */
break
;
default:
dbg_printf
(
"Unsupported yet tag %d
\n
"
,
tag1
);
return
FALSE
;
}
}
while
(
types_get_info
(
&
type1
,
TI_GET_TYPE
,
&
type1
.
id
)
&&
types_get_info
(
&
type2
,
TI_GET_TYPE
,
&
type2
.
id
));
return
FALSE
;
}
static
BOOL
is_basetype_char
(
DWORD
bt
)
{
return
bt
==
btChar
||
bt
==
btWChar
||
bt
==
btChar8
||
bt
==
btChar16
||
bt
==
btChar32
;
}
static
BOOL
is_basetype_integer
(
DWORD
bt
)
{
return
is_basetype_char
(
bt
)
||
bt
==
btInt
||
bt
==
btUInt
||
bt
==
btLong
||
bt
==
btULong
;
}
BOOL
types_is_integral_type
(
const
struct
dbg_lvalue
*
lv
)
{
struct
dbg_type
type
=
lv
->
type
;
DWORD
tag
,
bt
;
if
(
lv
->
bitlen
)
return
TRUE
;
if
(
!
types_get_real_type
(
&
type
,
&
tag
)
||
!
types_get_info
(
&
type
,
TI_GET_BASETYPE
,
&
bt
))
return
FALSE
;
return
is_basetype_integer
(
bt
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment