| OLD | NEW |
| 1 // Copyright (c) 2013 Google Inc. | 1 // Copyright (c) 2013 Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 | 188 |
| 189 uint64_t last_fp = last_frame->context.iregs[MD_CONTEXT_ARM64_REG_FP]; | 189 uint64_t last_fp = last_frame->context.iregs[MD_CONTEXT_ARM64_REG_FP]; |
| 190 | 190 |
| 191 uint64_t caller_fp = 0; | 191 uint64_t caller_fp = 0; |
| 192 if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { | 192 if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { |
| 193 BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" | 193 BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" |
| 194 << std::hex << last_fp; | 194 << std::hex << last_fp; |
| 195 return NULL; | 195 return NULL; |
| 196 } | 196 } |
| 197 | 197 |
| 198 // The memory at last_fp + 8 is the last frame's LR (callee's lr), which is |
| 199 // the PC of the caller. |
| 200 uint64_t caller_pc = 0; |
| 201 if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 8, &caller_pc)) { |
| 202 BPLOG(ERROR) << "Unable to read caller_pc from last_fp + 8: 0x" |
| 203 << std::hex << (last_fp + 8); |
| 204 return NULL; |
| 205 } |
| 206 |
| 198 uint64_t caller_lr = 0; | 207 uint64_t caller_lr = 0; |
| 199 if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 8, &caller_lr)) { | 208 if (last_fp && !memory_->GetMemoryAtAddress(caller_fp + 8, &caller_lr)) { |
| 200 BPLOG(ERROR) << "Unable to read caller_lr from last_fp + 8: 0x" | 209 BPLOG(ERROR) << "Unable to read caller_lr from caller_fp + 8: 0x" |
| 201 << std::hex << (last_fp + 8); | 210 << std::hex << (caller_fp + 8); |
| 202 return NULL; | 211 return NULL; |
| 203 } | 212 } |
| 204 | 213 |
| 205 uint64_t caller_sp = last_fp ? last_fp + 16 : | 214 uint64_t caller_sp = last_fp ? last_fp + 16 : |
| 206 last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP]; | 215 last_frame->context.iregs[MD_CONTEXT_ARM64_REG_SP]; |
| 207 | 216 |
| 208 // Create a new stack frame (ownership will be transferred to the caller) | 217 // Create a new stack frame (ownership will be transferred to the caller) |
| 209 // and fill it in. | 218 // and fill it in. |
| 210 StackFrameARM64* frame = new StackFrameARM64(); | 219 StackFrameARM64* frame = new StackFrameARM64(); |
| 211 | 220 |
| 212 frame->trust = StackFrame::FRAME_TRUST_FP; | 221 frame->trust = StackFrame::FRAME_TRUST_FP; |
| 213 frame->context = last_frame->context; | 222 frame->context = last_frame->context; |
| 214 frame->context.iregs[MD_CONTEXT_ARM64_REG_FP] = caller_fp; | 223 frame->context.iregs[MD_CONTEXT_ARM64_REG_FP] = caller_fp; |
| 215 frame->context.iregs[MD_CONTEXT_ARM64_REG_SP] = caller_sp; | 224 frame->context.iregs[MD_CONTEXT_ARM64_REG_SP] = caller_sp; |
| 216 frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] = | 225 frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] = caller_pc; |
| 217 last_frame->context.iregs[MD_CONTEXT_ARM64_REG_LR]; | |
| 218 frame->context.iregs[MD_CONTEXT_ARM64_REG_LR] = caller_lr; | 226 frame->context.iregs[MD_CONTEXT_ARM64_REG_LR] = caller_lr; |
| 219 frame->context_validity = StackFrameARM64::CONTEXT_VALID_PC | | 227 frame->context_validity = StackFrameARM64::CONTEXT_VALID_PC | |
| 220 StackFrameARM64::CONTEXT_VALID_LR | | 228 StackFrameARM64::CONTEXT_VALID_LR | |
| 221 StackFrameARM64::CONTEXT_VALID_FP | | 229 StackFrameARM64::CONTEXT_VALID_FP | |
| 222 StackFrameARM64::CONTEXT_VALID_SP; | 230 StackFrameARM64::CONTEXT_VALID_SP; |
| 223 return frame; | 231 return frame; |
| 224 } | 232 } |
| 225 | 233 |
| 226 StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, | 234 StackFrame* StackwalkerARM64::GetCallerFrame(const CallStack* stack, |
| 227 bool stack_scan_allowed) { | 235 bool stack_scan_allowed) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 // the return address gets back to the beginning of the call instruction. | 277 // the return address gets back to the beginning of the call instruction. |
| 270 // Callers that require the exact return address value may access | 278 // Callers that require the exact return address value may access |
| 271 // frame->context.iregs[MD_CONTEXT_ARM64_REG_PC]. | 279 // frame->context.iregs[MD_CONTEXT_ARM64_REG_PC]. |
| 272 frame->instruction = frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] - 4; | 280 frame->instruction = frame->context.iregs[MD_CONTEXT_ARM64_REG_PC] - 4; |
| 273 | 281 |
| 274 return frame.release(); | 282 return frame.release(); |
| 275 } | 283 } |
| 276 | 284 |
| 277 | 285 |
| 278 } // namespace google_breakpad | 286 } // namespace google_breakpad |
| OLD | NEW |