v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
ubsan.cc
Go to the documentation of this file.
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <stdint.h>
6#include <limits>
7
9
10#if !defined(UNDEFINED_SANITIZER) || !defined(V8_TARGET_ARCH_32_BIT)
11#error "This file is only needed for 32-bit UBSan builds."
12#endif
13
14// Compiling with -fsanitize=undefined on 32-bit platforms requires __mulodi4
15// to be available. Usually it comes from libcompiler_rt, which our build
16// doesn't provide, so here is a custom implementation (inspired by digit_mul
17// in src/objects/bigint.cc).
18extern "C" int64_t __mulodi4(int64_t a, int64_t b, int* overflow) {
19 // Multiply in 32-bit chunks.
20 // For inputs [AH AL]*[BH BL], the result is:
21 //
22 // [AL*BL] // r_low
23 // + [AL*BH] // r_mid1
24 // + [AH*BL] // r_mid2
25 // + [AH*BH] // r_high
26 // = [R4 R3 R2 R1] // high = [R4 R3], low = [R2 R1]
27 //
28 // Where of course we must be careful with carries between the columns.
29 uint64_t a_low = a & 0xFFFFFFFFu;
30 uint64_t a_high = static_cast<uint64_t>(a) >> 32;
31 uint64_t b_low = b & 0xFFFFFFFFu;
32 uint64_t b_high = static_cast<uint64_t>(b) >> 32;
33
34 uint64_t r_low = a_low * b_low;
35 uint64_t r_mid1 = a_low * b_high;
36 uint64_t r_mid2 = a_high * b_low;
37 uint64_t r_high = a_high * b_high;
38
39 uint64_t result1 = r_low + (r_mid1 << 32);
40 if (result1 < r_low) r_high++;
41 uint64_t result2 = result1 + (r_mid2 << 32);
42 if (result2 < result1) r_high++;
43 r_high += (r_mid1 >> 32) + (r_mid2 >> 32);
44 int64_t result = static_cast<int64_t>(result2);
45 uint64_t result_sign = (result >> 63);
46 uint64_t expected_result_sign = (a >> 63) ^ (b >> 63);
47
48 *overflow = (r_high > 0 || result_sign != expected_result_sign) ? 1 : 0;
49 return result;
50}
std::optional< TNode< JSArray > > a
ZoneVector< RpoNumber > & result
int64_t __mulodi4(int64_t a, int64_t b, int *overflow)
Definition ubsan.cc:18