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
33937f03
Commit
33937f03
authored
Sep 05, 2012
by
Piotr Caban
Committed by
Alexandre Julliard
Sep 05, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msvcrt: Support 64-bit RTTI in __RTDynamicCast.
parent
fbae5a95
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
140 additions
and
0 deletions
+140
-0
cpp.c
dlls/msvcrt/cpp.c
+113
-0
cpp.c
dlls/msvcrt/tests/cpp.c
+27
-0
No files found.
dlls/msvcrt/cpp.c
View file @
33937f03
...
...
@@ -117,6 +117,37 @@ static void dump_obj_locator( const rtti_object_locator *ptr )
}
}
#ifdef __x86_64__
static
void
dump_obj_locator_x64
(
const
rtti_object_locator_x64
*
ptr
)
{
int
i
;
char
*
base
=
(
char
*
)
ptr
-
ptr
->
object_locator
;
const
rtti_object_hierarchy_x64
*
h
=
(
const
rtti_object_hierarchy_x64
*
)(
base
+
ptr
->
type_hierarchy
);
const
type_info
*
type_descriptor
=
(
const
type_info
*
)(
base
+
ptr
->
type_descriptor
);
TRACE
(
"%p: sig=%08x base_offset=%08x flags=%08x type=%p %s hierarchy=%p
\n
"
,
ptr
,
ptr
->
signature
,
ptr
->
base_class_offset
,
ptr
->
flags
,
type_descriptor
,
dbgstr_type_info
(
type_descriptor
),
h
);
TRACE
(
" hierarchy: sig=%08x attr=%08x len=%d base classes=%p
\n
"
,
h
->
signature
,
h
->
attributes
,
h
->
array_len
,
base
+
h
->
base_classes
);
for
(
i
=
0
;
i
<
h
->
array_len
;
i
++
)
{
const
rtti_base_descriptor_x64
*
bases
=
(
rtti_base_descriptor_x64
*
)(
base
+
((
const
rtti_base_array_x64
*
)(
base
+
h
->
base_classes
))
->
bases
[
i
]);
TRACE
(
" base class %p: num %d off %d,%d,%d attr %08x type %p %s
\n
"
,
bases
,
bases
->
num_base_classes
,
bases
->
offsets
.
this_offset
,
bases
->
offsets
.
vbase_descr
,
bases
->
offsets
.
vbase_offset
,
bases
->
attributes
,
base
+
bases
->
type_descriptor
,
dbgstr_type_info
((
const
type_info
*
)(
base
+
bases
->
type_descriptor
))
);
}
}
#endif
/* Internal common ctor for exception */
static
void
EXCEPTION_ctor
(
exception
*
_this
,
const
char
**
name
)
{
...
...
@@ -919,6 +950,7 @@ const type_info* CDECL MSVCRT___RTtypeid(void *cppobj)
* This function is usually called by compiler generated code as a result
* of using one of the C++ dynamic cast statements.
*/
#ifndef __x86_64__
void
*
CDECL
MSVCRT___RTDynamicCast
(
void
*
cppobj
,
int
unknown
,
type_info
*
src
,
type_info
*
dst
,
int
do_throw
)
...
...
@@ -982,6 +1014,87 @@ void* CDECL MSVCRT___RTDynamicCast(void *cppobj, int unknown,
return
ret
;
}
#else
void
*
CDECL
MSVCRT___RTDynamicCast
(
void
*
cppobj
,
int
unknown
,
type_info
*
src
,
type_info
*
dst
,
int
do_throw
)
{
void
*
ret
;
if
(
!
cppobj
)
return
NULL
;
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
);
__TRY
{
int
i
;
const
rtti_object_locator
*
obj_locator
=
get_obj_locator
(
cppobj
);
if
(
obj_locator
->
signature
==
0
)
{
const
rtti_object_hierarchy
*
obj_bases
=
obj_locator
->
type_hierarchy
;
const
rtti_base_descriptor
*
const
*
base_desc
=
obj_bases
->
base_classes
->
bases
;
if
(
TRACE_ON
(
msvcrt
))
dump_obj_locator
(
obj_locator
);
ret
=
NULL
;
for
(
i
=
0
;
i
<
obj_bases
->
array_len
;
i
++
)
{
const
type_info
*
typ
=
base_desc
[
i
]
->
type_descriptor
;
if
(
!
strcmp
(
typ
->
mangled
,
dst
->
mangled
))
{
void
*
this_ptr
=
(
char
*
)
cppobj
-
obj_locator
->
base_class_offset
;
ret
=
get_this_pointer
(
&
base_desc
[
i
]
->
offsets
,
this_ptr
);
break
;
}
}
}
else
{
const
rtti_object_locator_x64
*
obj_locator_x64
=
(
const
rtti_object_locator_x64
*
)
obj_locator
;
const
char
*
base
=
(
const
char
*
)
obj_locator_x64
-
obj_locator_x64
->
object_locator
;
const
rtti_object_hierarchy_x64
*
obj_bases
=
(
const
rtti_object_hierarchy_x64
*
)(
base
+
obj_locator_x64
->
type_hierarchy
);
const
rtti_base_array_x64
*
base_array
=
(
const
rtti_base_array_x64
*
)(
base
+
obj_bases
->
base_classes
);
if
(
TRACE_ON
(
msvcrt
))
dump_obj_locator_x64
(
obj_locator_x64
);
ret
=
NULL
;
for
(
i
=
0
;
i
<
obj_bases
->
array_len
;
i
++
)
{
const
rtti_base_descriptor_x64
*
base_desc
=
(
const
rtti_base_descriptor_x64
*
)(
base
+
base_array
->
bases
[
i
]);
const
type_info
*
typ
=
(
const
type_info
*
)(
base
+
base_desc
->
type_descriptor
);
if
(
!
strcmp
(
typ
->
mangled
,
dst
->
mangled
))
{
void
*
this_ptr
=
(
char
*
)
cppobj
-
obj_locator_x64
->
base_class_offset
;
ret
=
get_this_pointer
(
&
base_desc
->
offsets
,
this_ptr
);
break
;
}
}
}
if
(
!
ret
&&
do_throw
)
{
const
char
*
msg
=
"Bad dynamic_cast!"
;
bad_cast
e
;
MSVCRT_bad_cast_ctor
(
&
e
,
&
msg
);
_CxxThrowException
(
&
e
,
&
bad_cast_exception_type
);
}
}
__EXCEPT_PAGE_FAULT
{
__non_rtti_object
e
;
MSVCRT___non_rtti_object_ctor
(
&
e
,
"Access violation - no RTTI data!"
);
_CxxThrowException
(
&
e
,
&
bad_typeid_exception_type
);
return
NULL
;
}
__ENDTRY
return
ret
;
}
#endif
/******************************************************************
* __RTCastToVoid (MSVCRT.@)
...
...
dlls/msvcrt/tests/cpp.c
View file @
33937f03
...
...
@@ -881,9 +881,17 @@ static void test_rtti(void)
{
{
RTTI_REF
(
simple_class_rtti
,
base_descriptor
[
0
])}
},
{
0
,
0
,
1
,
RTTI_REF
(
simple_class_rtti
,
base_array
)},
{
RTTI_SIGNATURE
,
0
,
0
,
RTTI_REF
(
simple_class_rtti
,
type_info
[
0
]),
RTTI_REF
(
simple_class_rtti
,
object_hierarchy
),
RTTI_REF
(
simple_class_rtti
,
object_locator
)}
},
child_class_rtti
=
{
{
{
NULL
,
NULL
,
"simple_class"
},
{
NULL
,
NULL
,
"child_class"
}
},
{
{
RTTI_REF
(
child_class_rtti
,
type_info
[
1
]),
0
,
{
4
,
-
1
,
0
},
0
},
{
RTTI_REF
(
child_class_rtti
,
type_info
[
0
]),
0
,
{
8
,
-
1
,
0
},
0
}
},
{
{
RTTI_REF
(
child_class_rtti
,
base_descriptor
[
0
]),
RTTI_REF
(
child_class_rtti
,
base_descriptor
[
1
])}
},
{
0
,
0
,
2
,
RTTI_REF
(
child_class_rtti
,
base_array
)},
{
RTTI_SIGNATURE
,
0
,
0
,
RTTI_REF
(
child_class_rtti
,
type_info
[
1
]),
RTTI_REF
(
child_class_rtti
,
object_hierarchy
),
RTTI_REF
(
child_class_rtti
,
object_locator
)}
};
void
*
simple_class_vtbl
[
2
]
=
{
&
simple_class_rtti
.
object_locator
};
void
*
simple_class
=
&
simple_class_vtbl
[
1
];
void
*
child_class_vtbl
[
2
]
=
{
&
child_class_rtti
.
object_locator
};
void
*
child_class
=
&
child_class_vtbl
[
1
];
static
const
char
*
e_name
=
"name"
;
type_info
*
ti
,
*
bti
;
...
...
@@ -923,6 +931,25 @@ static void test_rtti(void)
ti
=
p__RTtypeid
(
&
simple_class
);
ok
(
ti
&&
ti
->
mangled
&&
!
strcmp
(
ti
->
mangled
,
"simple_class"
),
"incorrect rtti data
\n
"
);
casted
=
p__RTCastToVoid
(
&
simple_class
);
ok
(
casted
==
(
void
*
)
&
simple_class
,
"failed cast to void
\n
"
);
ti
=
p__RTtypeid
(
&
child_class
);
ok
(
ti
&&
ti
->
mangled
&&
!
strcmp
(
ti
->
mangled
,
"child_class"
),
"incorrect rtti data
\n
"
);
casted
=
p__RTCastToVoid
(
&
child_class
);
ok
(
casted
==
(
void
*
)
&
child_class
,
"failed cast to void
\n
"
);
casted
=
p__RTDynamicCast
(
&
child_class
,
0
,
NULL
,
simple_class_rtti
.
type_info
,
0
);
if
(
casted
)
{
ok
(
casted
==
(
char
*
)
&
child_class
+
8
,
"failed cast to simple_class (%p %p)
\n
"
,
casted
,
&
child_class
);
}
casted
=
p__RTDynamicCast
(
&
child_class
,
0
,
&
child_class_rtti
.
type_info
[
0
],
&
child_class_rtti
.
type_info
[
1
],
0
);
ok
(
casted
==
(
char
*
)
&
child_class
+
4
,
"failed cast to child class (%p %p)
\n
"
,
casted
,
&
child_class
);
}
struct
_demangle
{
...
...
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