Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
b8d5d962
Commit
b8d5d962
authored
Oct 18, 2004
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed __RTDynamicCast to return the correct pointer for multiple
inheritance hierarchies (thanks to Muse Research for help with this one). Added some debug output.
parent
e62e88f4
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
92 additions
and
72 deletions
+92
-72
cpp.c
dlls/msvcrt/cpp.c
+45
-37
cppexcept.c
dlls/msvcrt/cppexcept.c
+12
-32
cppexcept.h
dlls/msvcrt/cppexcept.h
+35
-3
No files found.
dlls/msvcrt/cpp.c
View file @
b8d5d962
...
...
@@ -61,10 +61,8 @@ typedef struct _rtti_base_descriptor
{
type_info
*
type_descriptor
;
int
num_base_classes
;
int
base_class_offset
;
unsigned
int
flags
;
int
unknown1
;
int
unknown2
;
this_ptr_offsets
offsets
;
/* offsets for computing the this pointer */
unsigned
int
attributes
;
}
rtti_base_descriptor
;
typedef
struct
_rtti_base_array
...
...
@@ -74,15 +72,15 @@ typedef struct _rtti_base_array
typedef
struct
_rtti_object_hierarchy
{
int
unknown1
;
int
unknown2
;
unsigned
int
signature
;
unsigned
int
attributes
;
int
array_len
;
/* Size of the array pointed to by 'base_classes' */
const
rtti_base_array
*
base_classes
;
}
rtti_object_hierarchy
;
typedef
struct
_rtti_object_locator
{
int
unknown1
;
unsigned
int
signature
;
int
base_class_offset
;
unsigned
int
flags
;
type_info
*
type_descriptor
;
...
...
@@ -106,6 +104,30 @@ const exception_vtable MSVCRT_bad_cast_vtable;
const
exception_vtable
MSVCRT___non_rtti_object_vtable
;
static
const
exception_vtable
MSVCRT_type_info_vtable
;
static
void
dump_obj_locator
(
const
rtti_object_locator
*
ptr
)
{
int
i
;
const
rtti_object_hierarchy
*
h
=
ptr
->
type_hierarchy
;
TRACE
(
"%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p
\n
"
,
ptr
,
ptr
->
signature
,
ptr
->
base_class_offset
,
ptr
->
flags
,
ptr
->
type_descriptor
,
dbgstr_type_info
(
ptr
->
type_descriptor
),
ptr
->
type_hierarchy
);
TRACE
(
" hierarchy: sig=%08x attr=%08x len=%d base classes=%p
\n
"
,
h
->
signature
,
h
->
attributes
,
h
->
array_len
,
h
->
base_classes
);
for
(
i
=
0
;
i
<
h
->
array_len
;
i
++
)
{
TRACE
(
" base class %p: num %d off %d,%d,%d attr %08x type %p %s
\n
"
,
h
->
base_classes
->
bases
[
i
],
h
->
base_classes
->
bases
[
i
]
->
num_base_classes
,
h
->
base_classes
->
bases
[
i
]
->
offsets
.
this_offset
,
h
->
base_classes
->
bases
[
i
]
->
offsets
.
vbase_descr
,
h
->
base_classes
->
bases
[
i
]
->
offsets
.
vbase_offset
,
h
->
base_classes
->
bases
[
i
]
->
attributes
,
h
->
base_classes
->
bases
[
i
]
->
type_descriptor
,
dbgstr_type_info
(
h
->
base_classes
->
bases
[
i
]
->
type_descriptor
)
);
}
}
/* Internal common ctor for exception */
static
void
WINAPI
EXCEPTION_ctor
(
exception
*
_this
,
const
char
**
name
)
{
...
...
@@ -641,9 +663,7 @@ static const rtti_base_descriptor exception_rtti_base_descriptor =
{
&
exception_type_info
,
0
,
0
,
0
,
0
,
{
0
,
-
1
,
0
},
0
};
...
...
@@ -677,9 +697,7 @@ static const cxx_type_info exception_cxx_type_info =
{
0
,
&
exception_type_info
,
0
,
-
1
,
0
,
{
0
,
-
1
,
0
},
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT_exception_copy_ctor
};
...
...
@@ -695,9 +713,7 @@ static const rtti_base_descriptor bad_typeid_rtti_base_descriptor =
{
&
bad_typeid_type_info
,
1
,
0
,
0xffffffff
,
0
,
{
0
,
-
1
,
0
},
0
};
...
...
@@ -731,9 +747,7 @@ static const cxx_type_info bad_typeid_cxx_type_info =
{
0
,
&
bad_typeid_type_info
,
0
,
-
1
,
0
,
{
0
,
-
1
,
0
},
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT_bad_typeid_copy_ctor
};
...
...
@@ -749,9 +763,7 @@ static const rtti_base_descriptor bad_cast_rtti_base_descriptor =
{
&
bad_cast_type_info
,
1
,
0
,
0xffffffff
,
0
,
{
0
,
-
1
,
0
},
0
};
...
...
@@ -785,9 +797,7 @@ static const cxx_type_info bad_cast_cxx_type_info =
{
0
,
&
bad_cast_type_info
,
0
,
-
1
,
0
,
{
0
,
-
1
,
0
},
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT_bad_cast_copy_ctor
};
...
...
@@ -803,9 +813,7 @@ static const rtti_base_descriptor __non_rtti_object_rtti_base_descriptor =
{
&
__non_rtti_object_type_info
,
2
,
0
,
0xffffffff
,
0
,
{
0
,
-
1
,
0
},
0
};
...
...
@@ -839,9 +847,7 @@ static const cxx_type_info __non_rtti_object_cxx_type_info =
{
0
,
&
__non_rtti_object_type_info
,
0
,
-
1
,
0
,
{
0
,
-
1
,
0
},
sizeof
(
exception
),
(
cxx_copy_ctor
)
__thiscall_MSVCRT___non_rtti_object_copy_ctor
};
...
...
@@ -857,9 +863,7 @@ static const rtti_base_descriptor type_info_rtti_base_descriptor =
{
&
type_info_type_info
,
0
,
0
,
0xffffffff
,
0
,
{
0
,
-
1
,
0
},
0
};
...
...
@@ -1150,13 +1154,16 @@ void* MSVCRT___RTDynamicCast(type_info *cppobj, int unknown,
const
rtti_object_locator
*
obj_locator
;
/* Note: cppobj _isn't_ a type_info, we use that struct for its vtable ptr */
TRACE
(
"(%p,%d,%p,%p,%d)
\n
"
,
cppobj
,
unknown
,
src
,
dst
,
do_throw
);
TRACE
(
"obj: %p unknown: %d src: %p %s dst: %p %s do_throw: %d)
\n
"
,
cppobj
,
unknown
,
src
,
dbgstr_type_info
(
src
),
dst
,
dbgstr_type_info
(
dst
),
do_throw
);
if
(
!
cppobj
)
return
0
;
obj_locator
=
RTTI_GetObjectLocator
(
cppobj
);
if
(
unknown
)
FIXME
(
"Unknown parameter is non-zero: please report
\n
"
);
if
(
TRACE_ON
(
msvcrt
))
dump_obj_locator
(
obj_locator
);
/* To cast an object at runtime:
* 1.Find out the true type of the object from the typeinfo at vtable[-1]
* 2.Search for the destination type in the class hierarchy
...
...
@@ -1176,8 +1183,9 @@ void* MSVCRT___RTDynamicCast(type_info *cppobj, int unknown,
if
(
!
strcmp
(
typ
->
mangled
,
dst
->
mangled
))
{
dst_offset
=
(
*
base_desc
)
->
base_class_offset
;
break
;
/* compute the correct this pointer for that base class */
void
*
this_ptr
=
(
char
*
)
cppobj
-
obj_locator
->
base_class_offset
;
return
get_this_pointer
(
&
(
*
base_desc
)
->
offsets
,
this_ptr
);
}
base_desc
++
;
count
++
;
...
...
dlls/msvcrt/cppexcept.c
View file @
b8d5d962
...
...
@@ -76,12 +76,12 @@ inline static void call_dtor( void *func, void *object )
__asm__
__volatile__
(
"call *%0"
:
:
"r"
(
func
),
"c"
(
object
)
:
"eax"
,
"edx"
,
"memory"
);
}
static
void
dump_type
(
const
cxx_type_info
*
type
)
static
inline
void
dump_type
(
const
cxx_type_info
*
type
)
{
DPRINTF
(
"flags %x type %p
"
,
type
->
flags
,
type
->
type_info
);
if
(
type
->
type_info
)
DPRINTF
(
" (%p %s)"
,
type
->
type_info
->
name
,
type
->
type_info
->
mangled
);
DPRINTF
(
" offset %d vbase %d,%d size %d copy ctor %p
\n
"
,
type
->
this
_offset
,
type
->
vbase_descr
,
type
->
vbase_offset
,
type
->
size
,
type
->
copy_ctor
);
DPRINTF
(
"flags %x type %p
%s offsets %d,%d,%d size %d copy ctor %p
\n
"
,
type
->
flags
,
type
->
type_info
,
dbgstr_type_info
(
type
->
type_info
),
type
->
offsets
.
this_offset
,
type
->
offsets
.
vbase_descr
,
type
->
offsets
.
vbase
_offset
,
type
->
size
,
type
->
copy_ctor
);
}
static
void
dump_exception_type
(
const
cxx_exception_type
*
type
)
...
...
@@ -121,33 +121,13 @@ static void dump_function_descr( const cxx_function_descr *descr, const cxx_exce
for
(
j
=
0
;
j
<
descr
->
tryblock
[
i
].
catchblock_count
;
j
++
)
{
catchblock_info
*
ptr
=
&
descr
->
tryblock
[
i
].
catchblock
[
j
];
DPRINTF
(
" %d: flags %x offset %d handler %p type %p"
,
j
,
ptr
->
flags
,
ptr
->
offset
,
ptr
->
handler
,
ptr
->
type_info
);
if
(
ptr
->
type_info
)
DPRINTF
(
" (%p %s)"
,
ptr
->
type_info
->
name
,
ptr
->
type_info
->
mangled
);
DPRINTF
(
"
\n
"
);
DPRINTF
(
" %d: flags %x offset %d handler %p type %p %s
\n
"
,
j
,
ptr
->
flags
,
ptr
->
offset
,
ptr
->
handler
,
ptr
->
type_info
,
dbgstr_type_info
(
ptr
->
type_info
)
);
}
}
}
/* compute the this pointer for a base class of a given type */
static
void
*
get_this_pointer
(
const
cxx_type_info
*
type
,
void
*
object
)
{
void
*
this_ptr
;
int
*
offset_ptr
;
if
(
!
object
)
return
NULL
;
this_ptr
=
(
char
*
)
object
+
type
->
this_offset
;
if
(
type
->
vbase_descr
>=
0
)
{
/* move this ptr to vbase descriptor */
this_ptr
=
(
char
*
)
this_ptr
+
type
->
vbase_descr
;
/* and fetch additional offset from vbase descriptor */
offset_ptr
=
(
int
*
)(
*
(
char
**
)
this_ptr
+
type
->
vbase_offset
);
this_ptr
=
(
char
*
)
this_ptr
+
*
offset_ptr
;
}
return
this_ptr
;
}
/* check if the exception type is caught by a given catch block, and return the type that matched */
static
const
cxx_type_info
*
find_caught_type
(
cxx_exception_type
*
exc_type
,
catchblock_info
*
catchblock
)
{
...
...
@@ -185,21 +165,21 @@ static void copy_exception( void *object, cxx_exception_frame *frame,
if
(
catchblock
->
flags
&
TYPE_FLAG_REFERENCE
)
{
*
dest_ptr
=
get_this_pointer
(
type
,
object
);
*
dest_ptr
=
get_this_pointer
(
&
type
->
offsets
,
object
);
}
else
if
(
type
->
flags
&
CLASS_IS_SIMPLE_TYPE
)
{
memmove
(
dest_ptr
,
object
,
type
->
size
);
/* if it is a pointer, adjust it */
if
(
type
->
size
==
sizeof
(
void
*
))
*
dest_ptr
=
get_this_pointer
(
type
,
*
dest_ptr
);
if
(
type
->
size
==
sizeof
(
void
*
))
*
dest_ptr
=
get_this_pointer
(
&
type
->
offsets
,
*
dest_ptr
);
}
else
/* copy the object */
{
if
(
type
->
copy_ctor
)
call_copy_ctor
(
type
->
copy_ctor
,
dest_ptr
,
get_this_pointer
(
type
,
object
),
call_copy_ctor
(
type
->
copy_ctor
,
dest_ptr
,
get_this_pointer
(
&
type
->
offsets
,
object
),
(
type
->
flags
&
CLASS_HAS_VIRTUAL_BASE_CLASS
)
);
else
memmove
(
dest_ptr
,
get_this_pointer
(
type
,
object
),
type
->
size
);
memmove
(
dest_ptr
,
get_this_pointer
(
&
type
->
offsets
,
object
),
type
->
size
);
}
}
...
...
dlls/msvcrt/cppexcept.h
View file @
b8d5d962
...
...
@@ -84,14 +84,20 @@ typedef struct __cxx_function_descr
typedef
void
(
*
cxx_copy_ctor
)(
void
);
/* offsets for computing the this pointer */
typedef
struct
{
int
this_offset
;
/* offset of base class this pointer from start of object */
int
vbase_descr
;
/* offset of virtual base class descriptor */
int
vbase_offset
;
/* offset of this pointer offset in virtual base class descriptor */
}
this_ptr_offsets
;
/* complete information about a C++ type */
typedef
struct
__cxx_type_info
{
UINT
flags
;
/* flags (see CLASS_* flags below) */
type_info
*
type_info
;
/* C++ type info */
int
this_offset
;
/* offset of base class this pointer from start of object */
int
vbase_descr
;
/* offset of virtual base class descriptor */
int
vbase_offset
;
/* offset of this pointer offset in virtual base class descriptor */
this_ptr_offsets
offsets
;
/* offsets for computing the this pointer */
size_t
size
;
/* object size */
cxx_copy_ctor
copy_ctor
;
/* copy constructor */
}
cxx_type_info
;
...
...
@@ -121,4 +127,30 @@ typedef struct __cxx_exception_type
void
_CxxThrowException
(
void
*
,
const
cxx_exception_type
*
);
static
inline
const
char
*
dbgstr_type_info
(
const
type_info
*
info
)
{
if
(
!
info
)
return
"{}"
;
return
wine_dbg_sprintf
(
"{vtable=%p name=%s (%s)}"
,
info
->
vtable
,
info
->
mangled
,
info
->
name
?
info
->
name
:
""
);
}
/* compute the this pointer for a base class of a given type */
static
inline
void
*
get_this_pointer
(
const
this_ptr_offsets
*
off
,
void
*
object
)
{
void
*
this_ptr
;
int
*
offset_ptr
;
if
(
!
object
)
return
NULL
;
this_ptr
=
(
char
*
)
object
+
off
->
this_offset
;
if
(
off
->
vbase_descr
>=
0
)
{
/* move this ptr to vbase descriptor */
this_ptr
=
(
char
*
)
this_ptr
+
off
->
vbase_descr
;
/* and fetch additional offset from vbase descriptor */
offset_ptr
=
(
int
*
)(
*
(
char
**
)
this_ptr
+
off
->
vbase_offset
);
this_ptr
=
(
char
*
)
this_ptr
+
*
offset_ptr
;
}
return
this_ptr
;
}
#endif
/* __MSVCRT_CPPEXCEPT_H */
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