2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2016 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/relocation.h"
18 #include "hphp/runtime/vm/jit/relocation-arm.h"
19 #include "hphp/runtime/vm/jit/relocation-ppc64.h"
20 #include "hphp/runtime/vm/jit/relocation-x64.h"
22 #include "hphp/util/arch.h"
24 namespace HPHP
{ namespace jit
{
26 void RelocationInfo::recordRange(TCA start
, TCA end
,
27 TCA destStart
, TCA destEnd
) {
28 m_srcRanges
.emplace_back(start
, end
);
29 m_dstRanges
.emplace_back(destStart
, destEnd
);
30 m_adjustedAddresses
[start
].second
= destStart
;
31 m_adjustedAddresses
[end
].first
= destEnd
;
34 void RelocationInfo::recordAddress(TCA src
, TCA dest
, int range
) {
35 m_adjustedAddresses
.emplace(src
, std::make_pair(dest
, dest
+ range
));
38 TCA
RelocationInfo::adjustedAddressAfter(TCA addr
) const {
39 auto it
= m_adjustedAddresses
.find(addr
);
40 if (it
== m_adjustedAddresses
.end()) return nullptr;
42 return it
->second
.second
;
45 TCA
RelocationInfo::adjustedAddressBefore(TCA addr
) const {
46 auto it
= m_adjustedAddresses
.find(addr
);
47 if (it
== m_adjustedAddresses
.end()) return nullptr;
49 return it
->second
.first
;
52 void RelocationInfo::rewind(TCA start
, TCA end
) {
53 if (m_srcRanges
.size() && m_srcRanges
.back().first
== start
) {
54 assertx(m_dstRanges
.size() == m_srcRanges
.size());
55 assertx(m_srcRanges
.back().second
== end
);
56 m_srcRanges
.pop_back();
57 m_dstRanges
.pop_back();
59 auto it
= m_adjustedAddresses
.lower_bound(start
);
60 if (it
== m_adjustedAddresses
.end()) return;
62 // convenience function for erasing a m_smashableRelocations entry
63 auto eraseSmashableRelocation
= [this](TCA addr
) {
64 auto it
= m_smashableRelocations
.find(addr
);
65 if (it
!= m_smashableRelocations
.end()) m_smashableRelocations
.erase(it
);
68 if (it
->first
== start
) {
69 // if it->second.first is set, start is also the end
70 // of an existing region. Don't erase it in that case
71 if (it
->second
.first
) {
72 eraseSmashableRelocation(it
->second
.second
);
73 it
++->second
.second
= 0;
75 m_adjustedAddresses
.erase(it
++);
78 while (it
!= m_adjustedAddresses
.end() && it
->first
< end
) {
79 eraseSmashableRelocation(it
->second
.second
);
80 m_adjustedAddresses
.erase(it
++);
82 if (it
== m_adjustedAddresses
.end()) return;
83 if (it
->first
== end
) {
84 // Similar to start above, end could be the start of an
86 if (it
->second
.second
) {
87 eraseSmashableRelocation(it
->second
.second
);
88 it
++->second
.first
= 0;
90 m_adjustedAddresses
.erase(it
++);
95 //////////////////////////////////////////////////////////////////////
101 void adjustForRelocation(RelocationInfo
& rel
) {
102 return ARCH_SWITCH_CALL(adjustForRelocation
, rel
);
104 void adjustForRelocation(RelocationInfo
& rel
, TCA srcStart
, TCA srcEnd
) {
105 return ARCH_SWITCH_CALL(adjustForRelocation
, rel
, srcStart
, srcEnd
);
107 void adjustCodeForRelocation(RelocationInfo
& rel
, CGMeta
& fixups
) {
108 return ARCH_SWITCH_CALL(adjustCodeForRelocation
, rel
, fixups
);
110 void adjustMetaDataForRelocation(RelocationInfo
& rel
,
113 return ARCH_SWITCH_CALL(adjustMetaDataForRelocation
, rel
, asmInfo
, fixups
);
115 void findFixups(TCA start
, TCA end
, CGMeta
& fixups
) {
116 return ARCH_SWITCH_CALL(findFixups
, start
, end
, fixups
);
118 size_t relocate(RelocationInfo
& rel
,
119 CodeBlock
& destBlock
,
124 return ARCH_SWITCH_CALL(relocate
, rel
, destBlock
, start
, end
, srcBlock
,
128 //////////////////////////////////////////////////////////////////////