Commit f1cb51ad authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Let Runtime functions return a plain Address

instead of Object* (which is deprecated) or ObjectPtr (which is
unsuitable for cases where we need to control the ABI exactly).
Callers in generated code expect a plain tagged value, so return
precisely that. Same for C++ Builtins.

Bug: v8:3770
Change-Id: Id12f0d9830f7caf2a16aa973b8297f70d65241f5
Reviewed-on: https://chromium-review.googlesource.com/c/1382466Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58334}
parent 63ce4ba4
......@@ -88,8 +88,9 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
// TODO(cbruni): add global flag to check whether any tracing events have been
// enabled.
#define RUNTIME_FUNCTION_RETURNS_TYPE(Type, Name) \
static V8_INLINE Type __RT_impl_##Name(Arguments args, Isolate* isolate); \
#define RUNTIME_FUNCTION_RETURNS_TYPE(Type, InternalType, Convert, Name) \
static V8_INLINE InternalType __RT_impl_##Name(Arguments args, \
Isolate* isolate); \
\
V8_NOINLINE static Type Stats_##Name(int args_length, Address* args_object, \
Isolate* isolate) { \
......@@ -97,7 +98,7 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Runtime_" #Name); \
Arguments args(args_length, args_object); \
return __RT_impl_##Name(args, isolate); \
return Convert(__RT_impl_##Name(args, isolate)); \
} \
\
Type Name(int args_length, Address* args_object, Isolate* isolate) { \
......@@ -107,14 +108,20 @@ double ClobberDoubleRegisters(double x1, double x2, double x3, double x4);
return Stats_##Name(args_length, args_object, isolate); \
} \
Arguments args(args_length, args_object); \
return __RT_impl_##Name(args, isolate); \
return Convert(__RT_impl_##Name(args, isolate)); \
} \
\
static Type __RT_impl_##Name(Arguments args, Isolate* isolate)
static InternalType __RT_impl_##Name(Arguments args, Isolate* isolate)
#define RUNTIME_FUNCTION(Name) RUNTIME_FUNCTION_RETURNS_TYPE(Object*, Name)
#define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, Name)
#define CONVERT_OBJECT(x) (x)->ptr()
#define CONVERT_OBJECTPAIR(x) (x)
#define RUNTIME_FUNCTION(Name) \
RUNTIME_FUNCTION_RETURNS_TYPE(Address, Object*, CONVERT_OBJECT, Name)
#define RUNTIME_FUNCTION_RETURN_PAIR(Name) \
RUNTIME_FUNCTION_RETURNS_TYPE(ObjectPair, ObjectPair, CONVERT_OBJECTPAIR, \
Name)
} // namespace internal
} // namespace v8
......
......@@ -537,13 +537,13 @@ void Simulator::DoRuntimeCall(Instruction* instr) {
reinterpret_cast<SimulatorRuntimeCall>(external);
ObjectPair result =
target(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
TraceSim("Returned: {%p, %p}\n", static_cast<void*>(result.x),
static_cast<void*>(result.y));
TraceSim("Returned: {%p, %p}\n", reinterpret_cast<void*>(result.x),
reinterpret_cast<void*>(result.y));
#ifdef DEBUG
CorruptAllCallerSavedCPURegisters();
#endif
set_xreg(0, reinterpret_cast<int64_t>(result.x));
set_xreg(1, reinterpret_cast<int64_t>(result.y));
set_xreg(0, static_cast<int64_t>(result.x));
set_xreg(1, static_cast<int64_t>(result.y));
break;
}
......
......@@ -70,24 +70,24 @@ class BuiltinArguments : public Arguments {
V8_WARN_UNUSED_RESULT static Object* Builtin_Impl_##name( \
BuiltinArguments args, Isolate* isolate); \
\
V8_NOINLINE static Object* Builtin_Impl_Stats_##name( \
V8_NOINLINE static Address Builtin_Impl_Stats_##name( \
int args_length, Address* args_object, Isolate* isolate) { \
BuiltinArguments args(args_length, args_object); \
RuntimeCallTimerScope timer(isolate, \
RuntimeCallCounterId::kBuiltin_##name); \
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.runtime"), \
"V8.Builtin_" #name); \
return Builtin_Impl_##name(args, isolate); \
return Builtin_Impl_##name(args, isolate)->ptr(); \
} \
\
V8_WARN_UNUSED_RESULT Object* Builtin_##name( \
V8_WARN_UNUSED_RESULT Address Builtin_##name( \
int args_length, Address* args_object, Isolate* isolate) { \
DCHECK(isolate->context().is_null() || isolate->context()->IsContext()); \
if (V8_UNLIKELY(FLAG_runtime_stats)) { \
return Builtin_Impl_Stats_##name(args_length, args_object, isolate); \
} \
BuiltinArguments args(args_length, args_object); \
return Builtin_Impl_##name(args, isolate); \
return Builtin_Impl_##name(args, isolate)->ptr(); \
} \
\
V8_WARN_UNUSED_RESULT static Object* Builtin_Impl_##name( \
......
......@@ -21,7 +21,7 @@ namespace internal {
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
Object* Builtin_##Name(int argc, Address* args, Isolate* isolate);
Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
BUILTIN_LIST_C(FORWARD_DECLARE)
#undef FORWARD_DECLARE
......
......@@ -24,7 +24,7 @@ namespace internal {
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
Object* Builtin_##Name(int argc, Address* args, Isolate* isolate);
Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
BUILTIN_LIST_C(FORWARD_DECLARE)
#undef FORWARD_DECLARE
......
......@@ -65,7 +65,7 @@ const char* const
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
Object* Builtin_##Name(int argc, Address* args, Isolate* isolate);
Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
BUILTIN_LIST_C(FORWARD_DECLARE)
#undef FORWARD_DECLARE
......
......@@ -7,6 +7,7 @@
#include "src/base/logging.h"
#include "src/globals.h"
#include "src/objects.h"
#include "src/runtime/runtime.h"
namespace v8 {
......@@ -109,43 +110,24 @@ namespace internal {
// allocated by the caller, and passed as a pointer in a hidden first parameter.
#ifdef V8_HOST_ARCH_64_BIT
struct ObjectPair {
Object* x;
Object* y;
Address x;
Address y;
};
static inline ObjectPair MakePair(Object* x, Object* y) {
ObjectPair result = {x, y};
ObjectPair result = {x->ptr(), y->ptr()};
// Pointers x and y returned in rax and rdx, in AMD-x64-abi.
// In Win64 they are assigned to a hidden first argument.
return result;
}
#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
// For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
// are used in generated code. An alternative is using uint64_t and modifying
// generated code.
struct ObjectPair {
Object* x;
uint32_t x_upper;
Object* y;
uint32_t y_upper;
};
static inline ObjectPair MakePair(Object* x, Object* y) {
ObjectPair result = {x, 0, y, 0};
// Pointers x and y returned in rax and rdx, in x32-abi.
return result;
}
#else
typedef uint64_t ObjectPair;
static inline ObjectPair MakePair(Object* x, Object* y) {
#if defined(V8_TARGET_LITTLE_ENDIAN)
return reinterpret_cast<uint32_t>(x) |
(reinterpret_cast<ObjectPair>(y) << 32);
return x->ptr() | (static_cast<ObjectPair>(y->ptr()) << 32);
#elif defined(V8_TARGET_BIG_ENDIAN)
return reinterpret_cast<uint32_t>(y) |
(reinterpret_cast<ObjectPair>(x) << 32);
return y->ptr() | (static_cast<ObjectPair>(x->ptr()) << 32);
#else
#error Unknown endianness
#endif
......
......@@ -18,7 +18,7 @@ namespace internal {
// Header of runtime functions.
#define F(name, number_of_args, result_size) \
Object* Runtime_##name(int args_length, Address* args_object, \
Address Runtime_##name(int args_length, Address* args_object, \
Isolate* isolate);
FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
#undef F
......
......@@ -623,7 +623,7 @@ namespace internal {
#define FOR_EACH_INLINE_INTRINSIC(I) FOR_EACH_INTRINSIC_IMPL(NOTHING, I)
#define F(name, nargs, ressize) \
Object* Runtime_##name(int args_length, Address* args_object, \
Address Runtime_##name(int args_length, Address* args_object, \
Isolate* isolate);
FOR_EACH_INTRINSIC_RETURN_OBJECT(F)
#undef F
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment