• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "runtime/include/cframe.h"
17 #include "runtime/include/runtime.h"
18 #include "runtime/include/stack_walker.h"
19 
20 namespace panda {
21 
IsNativeMethod() const22 bool CFrame::IsNativeMethod() const
23 {
24     return GetMethod()->IsNative();
25 }
26 
SetVRegValue(const VRegInfo & vreg,uint64_t value,SlotType ** callee_stack)27 void CFrame::SetVRegValue(const VRegInfo &vreg, uint64_t value, SlotType **callee_stack)
28 {
29     auto location_value = static_cast<int>(vreg.GetValue());
30     switch (vreg.GetLocation()) {
31         case VRegInfo::Location::SLOT: {
32             SetValueToSlot(location_value, value);
33             if (!ArchTraits<ARCH>::IS_64_BITS && vreg.Has64BitValue()) {
34                 SetValueToSlot(location_value - 1, value >> BITS_PER_UINT32);
35             }
36             break;
37         }
38         case VRegInfo::Location::REGISTER:
39         case VRegInfo::Location::FP_REGISTER: {
40             bool is_fp = vreg.GetLocation() == VRegInfo::Location::FP_REGISTER;
41             if ((GetCallerRegsMask(ARCH, is_fp) & (1U << vreg.GetValue())) != 0) {
42                 CFrameLayout fl(ARCH, 0);
43                 auto reg_num = location_value - GetFirstCallerReg(ARCH, is_fp);
44                 reg_num = fl.GetCallerLastSlot(is_fp) - reg_num;
45                 SetValueToSlot(reg_num, value);
46                 if (!ArchTraits<ARCH>::IS_64_BITS && vreg.Has64BitValue()) {
47                     SetValueToSlot(static_cast<int>(reg_num) - 1, value >> BITS_PER_UINT32);
48                 }
49                 break;
50             }
51             WriteCalleeSavedRegister(location_value, value, is_fp, callee_stack);
52             if constexpr (!ArchTraits<ARCH>::IS_64_BITS) {  // NOLINT
53                 if (vreg.Has64BitValue()) {
54                     WriteCalleeSavedRegister(location_value + 1, value >> BITS_PER_UINT32, is_fp, callee_stack);
55                 }
56                 break;
57             }
58             break;
59         }
60         case VRegInfo::Location::CONSTANT:
61             ASSERT(false && "Modifying constants is not permitted");  // NOLINT(misc-static-assert)
62             break;
63         default:
64             UNREACHABLE();
65     }
66 }
67 
Dump(std::ostream & os,uint32_t max_slot)68 void CFrame::Dump(std::ostream &os, uint32_t max_slot)
69 {
70     if (IsJni()) {
71         os << "JNI CFRAME: fp=" << fp_ << std::endl;
72         return;
73     }
74     auto spill_start_slot = GetCalleeRegsCount(ARCH, false) + GetCalleeRegsCount(ARCH, true) +
75                             GetCallerRegsCount(ARCH, false) + GetCallerRegsCount(ARCH, true);
76     max_slot = max_slot > spill_start_slot ? (max_slot - spill_start_slot) : 0;
77 
78     auto print_mem = [](std::ostream &stream, void *addr, std::string_view dscr, uintptr_t value) {
79         constexpr size_t WIDTH = 16;
80         stream << ' ' << addr << ": " << std::setw(WIDTH) << std::setfill(' ') << dscr << " 0x" << std::hex << value
81                << std::dec << std::endl;
82     };
83     os << "****************************************\n";
84     os << "* CFRAME: fp=" << fp_ << ", max_spill_slot=" << max_slot << '\n';
85     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
86     print_mem(os, fp_ - CFrameLayout::LrSlot::Start(), "lr", GetLr());
87     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
88     print_mem(os, fp_ - CFrameLayout::PrevFrameSlot::Start(), "prev", reinterpret_cast<uintptr_t>(GetPrevFrame()));
89     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
90     print_mem(os, fp_ - CFrameLayout::MethodSlot::Start(), "method", reinterpret_cast<uintptr_t>(GetMethod()));
91     PandaString dscr;
92     size_t slot = 0;
93     DumpCalleeRegs(os, print_mem, &dscr, &slot);
94     DumpCalleeFPRegs(os, print_mem, &dscr, &slot);
95     DumpCallerRegs(os, print_mem, &dscr, &slot);
96     DumpCallerFPRegs(os, print_mem, &dscr, &slot);
97     DumpLocals(os, print_mem, &dscr, &slot, max_slot);
98 
99     os << "* CFRAME END\n";
100     os << "****************************************\n";
101 }
102 
DumpCalleeRegs(std::ostream & os,MemPrinter print_mem,PandaString * dscr,size_t * slot)103 void CFrame::DumpCalleeRegs(std::ostream &os, MemPrinter print_mem, PandaString *dscr, size_t *slot)
104 {
105     os << " [Callee saved registers]\n";
106     for (auto i = panda::helpers::ToSigned(GetLastCalleeReg(ARCH, false));
107          i >= panda::helpers::ToSigned(GetFirstCalleeReg(ARCH, false)); i--, (*slot)++) {
108         *dscr = "x" + ToPandaString(i) + ":" + ToPandaString(*slot);
109         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
110         print_mem(os, fp_ - CFrameLayout::STACK_START_SLOT - *slot, *dscr, GetValueFromSlot(*slot));
111     }
112 }
113 
DumpCalleeFPRegs(std::ostream & os,MemPrinter print_mem,PandaString * dscr,size_t * slot)114 void CFrame::DumpCalleeFPRegs(std::ostream &os, MemPrinter print_mem, PandaString *dscr, size_t *slot)
115 {
116     os << " [Callee saved FP registers]\n";
117     for (auto i = panda::helpers::ToSigned(GetLastCalleeReg(ARCH, true));
118          i >= panda::helpers::ToSigned(GetFirstCalleeReg(ARCH, true)); i--, (*slot)++) {
119         *dscr = "d" + ToPandaString(i) + ":" + ToPandaString(*slot);
120         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
121         print_mem(os, fp_ - CFrameLayout::STACK_START_SLOT - *slot, *dscr, GetValueFromSlot(*slot));
122     }
123 }
124 
DumpCallerRegs(std::ostream & os,MemPrinter print_mem,PandaString * dscr,size_t * slot)125 void CFrame::DumpCallerRegs(std::ostream &os, MemPrinter print_mem, PandaString *dscr, size_t *slot)
126 {
127     os << " [Caller saved registers] " << GetLastCallerReg(ARCH, false) << " " << GetFirstCallerReg(ARCH, false)
128        << "\n";
129     for (auto i = panda::helpers::ToSigned(GetLastCallerReg(ARCH, false));
130          i >= panda::helpers::ToSigned(GetFirstCallerReg(ARCH, false)); i--, (*slot)++) {
131         *dscr = "x" + ToPandaString(i) + ":" + ToPandaString(*slot);
132         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
133         print_mem(os, fp_ - CFrameLayout::STACK_START_SLOT - *slot, *dscr, GetValueFromSlot(*slot));
134     }
135 }
136 
DumpCallerFPRegs(std::ostream & os,MemPrinter print_mem,PandaString * dscr,size_t * slot)137 void CFrame::DumpCallerFPRegs(std::ostream &os, MemPrinter print_mem, PandaString *dscr, size_t *slot)
138 {
139     os << " [Caller saved FP registers]\n";
140     for (auto i = panda::helpers::ToSigned(GetLastCallerReg(ARCH, true));
141          i >= panda::helpers::ToSigned(GetFirstCallerReg(ARCH, true)); i--, (*slot)++) {
142         *dscr = "d" + ToPandaString(i) + ":" + ToPandaString(*slot);
143         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
144         print_mem(os, fp_ - CFrameLayout::STACK_START_SLOT - *slot, *dscr, GetValueFromSlot(*slot));
145     }
146 }
147 
DumpLocals(std::ostream & os,MemPrinter print_mem,PandaString * dscr,size_t * slot,int32_t max_slot)148 void CFrame::DumpLocals(std::ostream &os, MemPrinter print_mem, PandaString *dscr, size_t *slot, int32_t max_slot)
149 {
150     os << " [Locals]\n";
151     for (auto i = 0; i <= max_slot; i++, (*slot)++) {
152         *dscr = "s" + ToPandaString(i) + ":" + ToPandaString(*slot);
153         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
154         print_mem(os, fp_ - CFrameLayout::STACK_START_SLOT - *slot, *dscr, GetValueFromSlot(*slot));
155     }
156 }
157 
158 }  // namespace panda
159