| 143 | } |
| 144 | |
| 145 | bool StackFrame::unwindStub(instruction_t* entry, const char* name, uintptr_t& pc, uintptr_t& sp, uintptr_t& fp) { |
| 146 | instruction_t* ip = (instruction_t*)pc; |
| 147 | if (ip == entry || *ip == 0xd65f03c0) { |
| 148 | pc = link(); |
| 149 | return true; |
| 150 | } else if (entry != NULL && entry[0] == 0xa9bf7bfd) { |
| 151 | // The stub begins with |
| 152 | // stp x29, x30, [sp, #-16]! |
| 153 | // mov x29, sp |
| 154 | if (ip == entry + 1) { |
| 155 | sp += 16; |
| 156 | pc = ((uintptr_t*)sp)[-1]; |
| 157 | return true; |
| 158 | } else if (entry[1] == 0x910003fd && withinCurrentStack(fp)) { |
| 159 | sp = fp + 16; |
| 160 | fp = ((uintptr_t*)sp)[-2]; |
| 161 | pc = ((uintptr_t*)sp)[-1]; |
| 162 | return true; |
| 163 | } |
| 164 | } else if (entry != NULL && isSTP(entry[0]) && isFixedSizeFrame(name)) { |
| 165 | // The stub begins with |
| 166 | // stp xn, xm, [sp, #-imm]! |
| 167 | int offset = int(entry[0] << 10) >> 25; |
| 168 | sp = (intptr_t)sp - offset * 8; |
| 169 | pc = link(); |
| 170 | return true; |
| 171 | } else if (isZeroSizeFrame(name)) { |
| 172 | // Should be done after isSTP check, since frame size may vary between JVM versions |
| 173 | pc = link(); |
| 174 | return true; |
| 175 | } |
| 176 | return false; |
| 177 | } |
| 178 | |
| 179 | static inline bool isFrameComplete(instruction_t* entry, instruction_t* ip) { |
| 180 | // Frame is fully constructed after sp is decremented by the frame size. |
nothing calls this directly
no test coverage detected