summaryrefslogtreecommitdiffstats
path: root/js/src/jit/x86-shared/Patching-x86-shared.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/x86-shared/Patching-x86-shared.h')
-rw-r--r--js/src/jit/x86-shared/Patching-x86-shared.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/js/src/jit/x86-shared/Patching-x86-shared.h b/js/src/jit/x86-shared/Patching-x86-shared.h
new file mode 100644
index 0000000000..85c523cd15
--- /dev/null
+++ b/js/src/jit/x86-shared/Patching-x86-shared.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * 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, uint32_t trailing = 0) {
+ memcpy((char*)where - trailing - sizeof(int32_t), &value, sizeof(int32_t));
+}
+
+inline void SetRel32(void* from, void* to, uint32_t trailing = 0) {
+ 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, trailing);
+}
+
+inline void* GetRel32Target(void* where) {
+ int32_t rel = GetInt32(where);
+ return (char*)where + rel;
+}
+
+// JmpSrc represents a positive offset within a code buffer, or an uninitialized
+// value. Lots of code depends on uninitialized JmpSrc holding the value -1, on
+// -1 being a legal value of JmpSrc, and on being able to initialize a JmpSrc
+// with the value -1.
+//
+// The value of the `offset` is always positive and <= MaxCodeBytesPerProcess,
+// see ProcessExecutableMemory.h. The latter quantity in turn must fit in an
+// i32. But we further require that the value is not precisely INT32_MAX, so as
+// to allow the JmpSrc value -1 to mean "uninitialized" without ambiguity.
+//
+// The quantity `trailing` denotes the number of bytes of data that follow the
+// patch field in the instruction. The offset points to the end of the
+// instruction as per normal. The information about trailing bytes is needed
+// separately from the offset to correctly patch instructions that have
+// immediates trailing the patch field (eg CMPSS and CMPSD). Currently the only
+// allowed values for `trailing` are 0 and 1.
+
+static_assert(MaxCodeBytesPerProcess < size_t(INT32_MAX), "Invariant");
+
+class JmpSrc {
+ public:
+ JmpSrc() : offset_(INT32_MAX), trailing_(0) {}
+ explicit JmpSrc(int32_t offset) : offset_(offset), trailing_(0) {
+ // offset -1 is stored as INT32_MAX
+ MOZ_ASSERT(offset == -1 || (offset >= 0 && offset < INT32_MAX));
+ }
+ JmpSrc(int32_t offset, uint32_t trailing)
+ : offset_(offset), trailing_(trailing) {
+ // Disallow offset -1 in this situation, it does not apply.
+ MOZ_ASSERT(offset >= 0 && offset < INT32_MAX);
+ MOZ_ASSERT(trailing <= 1);
+ }
+ int32_t offset() const {
+ return offset_ == INT32_MAX ? -1 : int32_t(offset_);
+ }
+ uint32_t trailing() const { return trailing_; }
+
+ private:
+ uint32_t offset_ : 31;
+ uint32_t trailing_ : 1;
+};
+
+class JmpDst {
+ public:
+ explicit JmpDst(int32_t offset) : offset_(offset) {}
+ int32_t offset() const { return offset_; }
+
+ private:
+ int32_t offset_;
+};
+
+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 */