tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Patching-x86-shared.h (3808B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef jit_x86_shared_Patching_x86_shared_h
      8 #define jit_x86_shared_Patching_x86_shared_h
      9 
     10 namespace js {
     11 namespace jit {
     12 
     13 namespace X86Encoding {
     14 
     15 inline void* GetPointer(const void* where) {
     16  void* res;
     17  memcpy(&res, (const char*)where - sizeof(void*), sizeof(void*));
     18  return res;
     19 }
     20 
     21 inline void SetPointer(void* where, const void* value) {
     22  memcpy((char*)where - sizeof(void*), &value, sizeof(void*));
     23 }
     24 
     25 inline int32_t GetInt32(const void* where) {
     26  int32_t res;
     27  memcpy(&res, (const char*)where - sizeof(int32_t), sizeof(int32_t));
     28  return res;
     29 }
     30 
     31 inline void SetInt32(void* where, int32_t value, uint32_t trailing = 0) {
     32  memcpy((char*)where - trailing - sizeof(int32_t), &value, sizeof(int32_t));
     33 }
     34 
     35 inline void SetRel32(void* from, void* to, uint32_t trailing = 0) {
     36  intptr_t offset =
     37      reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
     38  MOZ_ASSERT(offset == static_cast<int32_t>(offset),
     39             "offset is too great for a 32-bit relocation");
     40  if (offset != static_cast<int32_t>(offset)) {
     41    MOZ_CRASH("offset is too great for a 32-bit relocation");
     42  }
     43 
     44  SetInt32(from, offset, trailing);
     45 }
     46 
     47 inline void* GetRel32Target(void* where) {
     48  int32_t rel = GetInt32(where);
     49  return (char*)where + rel;
     50 }
     51 
     52 // JmpSrc represents a positive offset within a code buffer, or an uninitialized
     53 // value.  Lots of code depends on uninitialized JmpSrc holding the value -1, on
     54 // -1 being a legal value of JmpSrc, and on being able to initialize a JmpSrc
     55 // with the value -1.
     56 //
     57 // The value of the `offset` is always positive and <= MaxCodeBytesPerProcess,
     58 // see ProcessExecutableMemory.h.  The latter quantity in turn must fit in an
     59 // i32.  But we further require that the value is not precisely INT32_MAX, so as
     60 // to allow the JmpSrc value -1 to mean "uninitialized" without ambiguity.
     61 //
     62 // The quantity `trailing` denotes the number of bytes of data that follow the
     63 // patch field in the instruction.  The offset points to the end of the
     64 // instruction as per normal.  The information about trailing bytes is needed
     65 // separately from the offset to correctly patch instructions that have
     66 // immediates trailing the patch field (eg CMPSS and CMPSD).  Currently the only
     67 // allowed values for `trailing` are 0 and 1.
     68 
     69 static_assert(MaxCodeBytesPerProcess < size_t(INT32_MAX), "Invariant");
     70 
     71 class JmpSrc {
     72 public:
     73  JmpSrc() : offset_(INT32_MAX), trailing_(0) {}
     74  explicit JmpSrc(int32_t offset) : offset_(offset), trailing_(0) {
     75    // offset -1 is stored as INT32_MAX
     76    MOZ_ASSERT(offset == -1 || (offset >= 0 && offset < INT32_MAX));
     77  }
     78  JmpSrc(int32_t offset, uint32_t trailing)
     79      : offset_(offset), trailing_(trailing) {
     80    // Disallow offset -1 in this situation, it does not apply.
     81    MOZ_ASSERT(offset >= 0 && offset < INT32_MAX);
     82    MOZ_ASSERT(trailing <= 1);
     83  }
     84  int32_t offset() const {
     85    return offset_ == INT32_MAX ? -1 : int32_t(offset_);
     86  }
     87  uint32_t trailing() const { return trailing_; }
     88 
     89 private:
     90  uint32_t offset_ : 31;
     91  uint32_t trailing_ : 1;
     92 };
     93 
     94 class JmpDst {
     95 public:
     96  explicit JmpDst(int32_t offset) : offset_(offset) {}
     97  int32_t offset() const { return offset_; }
     98 
     99 private:
    100  int32_t offset_;
    101 };
    102 
    103 inline bool CanRelinkJump(void* from, void* to) {
    104  intptr_t offset = static_cast<char*>(to) - static_cast<char*>(from);
    105  return (offset == static_cast<int32_t>(offset));
    106 }
    107 
    108 }  // namespace X86Encoding
    109 
    110 }  // namespace jit
    111 }  // namespace js
    112 
    113 #endif /* jit_x86_shared_Patching_x86_shared_h */