Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: src/processor/stackwalker_arm64.cc

Issue 1884503002: Fix arm64 frame-pointer stackwalker Base URL: https://chromium.googlesource.com/breakpad/breakpad.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698