summaryrefslogtreecommitdiffstats
path: root/js/src/jit/x86-shared/Patching-x86-shared.h
blob: b7349287052f27dc4203f3e407206af2df9c92e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_x86_shared_Patching_x86_shared_h
#define jit_x86_shared_Patching_x86_shared_h

namespace js {
namespace jit {

namespace X86Encoding {

inline void*
GetPointer(const void* where)
{
    void* res;
    memcpy(&res, (const char*)where - sizeof(void*), sizeof(void*));
    return res;
}

inline void
SetPointer(void* where, const void* value)
{
    memcpy((char*)where - sizeof(void*), &value, sizeof(void*));
}

inline int32_t
GetInt32(const void* where)
{
    int32_t res;
    memcpy(&res, (const char*)where - sizeof(int32_t), sizeof(int32_t));
    return res;
}

inline void
SetInt32(void* where, int32_t value)
{
    memcpy((char*)where - sizeof(int32_t), &value, sizeof(int32_t));
}

inline void
SetRel32(void* from, void* to)
{
    intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
    MOZ_ASSERT(offset == static_cast<int32_t>(offset),
               "offset is too great for a 32-bit relocation");
    if (offset != static_cast<int32_t>(offset))
        MOZ_CRASH("offset is too great for a 32-bit relocation");

    SetInt32(from, offset);
}

inline void*
GetRel32Target(void* where)
{
    int32_t rel = GetInt32(where);
    return (char*)where + rel;
}

class JmpSrc {
  public:
    JmpSrc()
        : offset_(-1)
    {
    }

    explicit JmpSrc(int32_t offset)
        : offset_(offset)
    {
    }

    int32_t offset() const {
        return offset_;
    }

    bool isSet() const {
        return offset_ != -1;
    }

  private:
    int offset_;
};

class JmpDst {
  public:
    JmpDst()
        : offset_(-1)
        , used_(false)
    {
    }

    bool isUsed() const { return used_; }
    void used() { used_ = true; }
    bool isValid() const { return offset_ != -1; }

    explicit JmpDst(int32_t offset)
        : offset_(offset)
        , used_(false)
    {
        MOZ_ASSERT(offset_ == offset);
    }
    int32_t offset() const {
        return offset_;
    }
  private:
    int32_t offset_ : 31;
    bool used_ : 1;
};

inline bool
CanRelinkJump(void* from, void* to)
{
    intptr_t offset = static_cast<char*>(to) - static_cast<char*>(from);
    return (offset == static_cast<int32_t>(offset));
}

} // namespace X86Encoding

} // namespace jit
} // namespace js

#endif /* jit_x86_shared_Patching_x86_shared_h */