stackwalker_riscv.cc
1 // Copyright 2013 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 /* stackwalker_riscv.cc: riscv-specific stackwalker. 30 * 31 * See stackwalker_riscv.h for documentation. 32 * 33 * Author: Iacopo Colonnelli 34 */ 35 36 #ifdef HAVE_CONFIG_H 37 #include <config.h> // Must come first 38 #endif 39 40 #include "common/scoped_ptr.h" 41 #include "google_breakpad/processor/call_stack.h" 42 #include "google_breakpad/processor/code_modules.h" 43 #include "google_breakpad/processor/memory_region.h" 44 #include "google_breakpad/processor/stack_frame_cpu.h" 45 #include "google_breakpad/processor/system_info.h" 46 #include "processor/cfi_frame_info.h" 47 #include "processor/logging.h" 48 #include "processor/stackwalker_riscv.h" 49 50 namespace google_breakpad { 51 52 StackwalkerRISCV::StackwalkerRISCV(const SystemInfo* system_info, 53 const MDRawContextRISCV* context, 54 MemoryRegion* memory, 55 const CodeModules* modules, 56 StackFrameSymbolizer* resolver_helper) 57 : Stackwalker(system_info, memory, modules, resolver_helper), 58 context_(context), 59 context_frame_validity_(StackFrameRISCV::CONTEXT_VALID_ALL) { 60 } 61 62 63 StackFrame* StackwalkerRISCV::GetContextFrame() { 64 if (!context_) { 65 BPLOG(ERROR) << "Can't get context frame without context"; 66 return NULL; 67 } 68 69 StackFrameRISCV* frame = new StackFrameRISCV(); 70 71 frame->context = *context_; 72 frame->context_validity = context_frame_validity_; 73 frame->trust = StackFrame::FRAME_TRUST_CONTEXT; 74 frame->instruction = frame->context.pc; 75 76 return frame; 77 } 78 79 StackFrameRISCV* StackwalkerRISCV::GetCallerByCFIFrameInfo( 80 const vector<StackFrame*>& frames, 81 CFIFrameInfo* cfi_frame_info) { 82 StackFrameRISCV* last_frame = 83 static_cast<StackFrameRISCV*>(frames.back()); 84 85 // Populate a dictionary with the valid register values in last_frame. 86 CFIFrameInfo::RegisterValueMap<uint32_t> callee_registers; 87 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_PC) 88 callee_registers["pc"] = last_frame->context.pc; 89 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_RA) 90 callee_registers["ra"] = last_frame->context.ra; 91 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_SP) 92 callee_registers["sp"] = last_frame->context.sp; 93 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_GP) 94 callee_registers["gp"] = last_frame->context.gp; 95 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_TP) 96 callee_registers["tp"] = last_frame->context.tp; 97 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T0) 98 callee_registers["t0"] = last_frame->context.t0; 99 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T1) 100 callee_registers["t1"] = last_frame->context.t1; 101 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T2) 102 callee_registers["t2"] = last_frame->context.t2; 103 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S0) 104 callee_registers["s0"] = last_frame->context.s0; 105 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S1) 106 callee_registers["s1"] = last_frame->context.s1; 107 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A0) 108 callee_registers["a0"] = last_frame->context.a0; 109 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A1) 110 callee_registers["a1"] = last_frame->context.a1; 111 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A2) 112 callee_registers["a2"] = last_frame->context.a2; 113 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A3) 114 callee_registers["a3"] = last_frame->context.a3; 115 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A4) 116 callee_registers["a4"] = last_frame->context.a4; 117 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A5) 118 callee_registers["a5"] = last_frame->context.a5; 119 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A6) 120 callee_registers["a6"] = last_frame->context.a6; 121 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_A7) 122 callee_registers["a7"] = last_frame->context.a7; 123 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S2) 124 callee_registers["s2"] = last_frame->context.s2; 125 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S3) 126 callee_registers["s3"] = last_frame->context.s3; 127 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S4) 128 callee_registers["s4"] = last_frame->context.s4; 129 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S5) 130 callee_registers["s5"] = last_frame->context.s5; 131 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S6) 132 callee_registers["s6"] = last_frame->context.s6; 133 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S7) 134 callee_registers["s7"] = last_frame->context.s7; 135 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S8) 136 callee_registers["s8"] = last_frame->context.s8; 137 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S9) 138 callee_registers["s9"] = last_frame->context.s9; 139 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S10) 140 callee_registers["s10"] = last_frame->context.s10; 141 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_S11) 142 callee_registers["s11"] = last_frame->context.s11; 143 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T3) 144 callee_registers["t3"] = last_frame->context.t3; 145 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T4) 146 callee_registers["t4"] = last_frame->context.t4; 147 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T5) 148 callee_registers["t5"] = last_frame->context.t5; 149 if (last_frame->context_validity & StackFrameRISCV::CONTEXT_VALID_T6) 150 callee_registers["t6"] = last_frame->context.t6; 151 152 // Use the STACK CFI data to recover the caller's register values. 153 CFIFrameInfo::RegisterValueMap<uint32_t> caller_registers; 154 if (!cfi_frame_info->FindCallerRegs(callee_registers, *memory_, 155 &caller_registers)) { 156 return NULL; 157 } 158 159 // Construct a new stack frame given the values the CFI recovered. 160 CFIFrameInfo::RegisterValueMap<uint32_t>::iterator entry; 161 scoped_ptr<StackFrameRISCV> frame(new StackFrameRISCV()); 162 entry = caller_registers.find("pc"); 163 if (entry != caller_registers.end()) { 164 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_PC; 165 frame->context.pc = entry->second; 166 } else{ 167 // If the CFI doesn't recover the PC explicitly, then use .ra. 168 entry = caller_registers.find(".ra"); 169 if (entry != caller_registers.end()) { 170 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_PC; 171 frame->context.pc = entry->second; 172 } 173 } 174 entry = caller_registers.find("ra"); 175 if (entry != caller_registers.end()) { 176 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_RA; 177 frame->context.ra = entry->second; 178 } 179 entry = caller_registers.find("sp"); 180 if (entry != caller_registers.end()) { 181 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_SP; 182 frame->context.sp = entry->second; 183 } else { 184 // If the CFI doesn't recover the SP explicitly, then use .cfa. 185 entry = caller_registers.find(".cfa"); 186 if (entry != caller_registers.end()) { 187 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_SP; 188 frame->context.sp = entry->second; 189 } 190 } 191 entry = caller_registers.find("gp"); 192 if (entry != caller_registers.end()) { 193 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_GP; 194 frame->context.gp = entry->second; 195 } 196 entry = caller_registers.find("tp"); 197 if (entry != caller_registers.end()) { 198 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_TP; 199 frame->context.tp = entry->second; 200 } 201 entry = caller_registers.find("t0"); 202 if (entry != caller_registers.end()) { 203 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T0; 204 frame->context.t0 = entry->second; 205 } 206 entry = caller_registers.find("t1"); 207 if (entry != caller_registers.end()) { 208 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T1; 209 frame->context.t1 = entry->second; 210 } 211 entry = caller_registers.find("t2"); 212 if (entry != caller_registers.end()) { 213 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T2; 214 frame->context.t2 = entry->second; 215 } 216 entry = caller_registers.find("s0"); 217 if (entry != caller_registers.end()) { 218 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S0; 219 frame->context.s0 = entry->second; 220 } else if (last_frame->context_validity & 221 StackFrameRISCV::CONTEXT_VALID_S0) { 222 // Since the register is callee-saves, assume the callee 223 // has not yet changed it. 224 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S0; 225 frame->context.s0 = last_frame->context.s0; 226 } 227 entry = caller_registers.find("s1"); 228 if (entry != caller_registers.end()) { 229 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S1; 230 frame->context.s1 = entry->second; 231 } else if (last_frame->context_validity & 232 StackFrameRISCV::CONTEXT_VALID_S1) { 233 // Since the register is callee-saves, assume the callee 234 // has not yet changed it. 235 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S1; 236 frame->context.s1 = last_frame->context.s1; 237 } 238 entry = caller_registers.find("a0"); 239 if (entry != caller_registers.end()) { 240 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A0; 241 frame->context.a0 = entry->second; 242 } 243 entry = caller_registers.find("a1"); 244 if (entry != caller_registers.end()) { 245 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A1; 246 frame->context.a1 = entry->second; 247 } 248 entry = caller_registers.find("a2"); 249 if (entry != caller_registers.end()) { 250 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A2; 251 frame->context.a2 = entry->second; 252 } 253 entry = caller_registers.find("a3"); 254 if (entry != caller_registers.end()) { 255 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A3; 256 frame->context.a3 = entry->second; 257 } 258 entry = caller_registers.find("a4"); 259 if (entry != caller_registers.end()) { 260 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A4; 261 frame->context.a4 = entry->second; 262 } 263 entry = caller_registers.find("a5"); 264 if (entry != caller_registers.end()) { 265 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A5; 266 frame->context.a5 = entry->second; 267 } 268 entry = caller_registers.find("a6"); 269 if (entry != caller_registers.end()) { 270 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A6; 271 frame->context.a6 = entry->second; 272 } 273 entry = caller_registers.find("a7"); 274 if (entry != caller_registers.end()) { 275 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_A7; 276 frame->context.a7 = entry->second; 277 } 278 entry = caller_registers.find("s2"); 279 if (entry != caller_registers.end()) { 280 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S2; 281 frame->context.s2 = entry->second; 282 } else if (last_frame->context_validity & 283 StackFrameRISCV::CONTEXT_VALID_S2) { 284 // Since the register is callee-saves, assume the callee 285 // has not yet changed it. 286 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S2; 287 frame->context.s2 = last_frame->context.s2; 288 } 289 entry = caller_registers.find("s3"); 290 if (entry != caller_registers.end()) { 291 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S3; 292 frame->context.s3 = entry->second; 293 } else if (last_frame->context_validity & 294 StackFrameRISCV::CONTEXT_VALID_S3) { 295 // Since the register is callee-saves, assume the callee 296 // has not yet changed it. 297 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S3; 298 frame->context.s3 = last_frame->context.s3; 299 } 300 entry = caller_registers.find("s4"); 301 if (entry != caller_registers.end()) { 302 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S4; 303 frame->context.s4 = entry->second; 304 } else if (last_frame->context_validity & 305 StackFrameRISCV::CONTEXT_VALID_S4) { 306 // Since the register is callee-saves, assume the callee 307 // has not yet changed it. 308 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S4; 309 frame->context.s4 = last_frame->context.s4; 310 } 311 entry = caller_registers.find("s5"); 312 if (entry != caller_registers.end()) { 313 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S5; 314 frame->context.s5 = entry->second; 315 } else if (last_frame->context_validity & 316 StackFrameRISCV::CONTEXT_VALID_S5) { 317 // Since the register is callee-saves, assume the callee 318 // has not yet changed it. 319 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S5; 320 frame->context.s5 = last_frame->context.s5; 321 } 322 entry = caller_registers.find("s6"); 323 if (entry != caller_registers.end()) { 324 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S6; 325 frame->context.s6 = entry->second; 326 } else if (last_frame->context_validity & 327 StackFrameRISCV::CONTEXT_VALID_S6) { 328 // Since the register is callee-saves, assume the callee 329 // has not yet changed it. 330 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S6; 331 frame->context.s6 = last_frame->context.s6; 332 } 333 entry = caller_registers.find("s7"); 334 if (entry != caller_registers.end()) { 335 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S7; 336 frame->context.s7 = entry->second; 337 } else if (last_frame->context_validity & 338 StackFrameRISCV::CONTEXT_VALID_S7) { 339 // Since the register is callee-saves, assume the callee 340 // has not yet changed it. 341 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S7; 342 frame->context.s7 = last_frame->context.s7; 343 } 344 entry = caller_registers.find("s8"); 345 if (entry != caller_registers.end()) { 346 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S8; 347 frame->context.s8 = entry->second; 348 } else if (last_frame->context_validity & 349 StackFrameRISCV::CONTEXT_VALID_S8) { 350 // Since the register is callee-saves, assume the callee 351 // has not yet changed it. 352 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S8; 353 frame->context.s8 = last_frame->context.s8; 354 } 355 entry = caller_registers.find("s9"); 356 if (entry != caller_registers.end()) { 357 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S9; 358 frame->context.s9 = entry->second; 359 } else if (last_frame->context_validity & 360 StackFrameRISCV::CONTEXT_VALID_S9) { 361 // Since the register is callee-saves, assume the callee 362 // has not yet changed it. 363 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S9; 364 frame->context.s9 = last_frame->context.s9; 365 } 366 entry = caller_registers.find("s10"); 367 if (entry != caller_registers.end()) { 368 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S10; 369 frame->context.s10 = entry->second; 370 } else if (last_frame->context_validity & 371 StackFrameRISCV::CONTEXT_VALID_S10) { 372 // Since the register is callee-saves, assume the callee 373 // has not yet changed it. 374 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S10; 375 frame->context.s10 = last_frame->context.s10; 376 } 377 entry = caller_registers.find("s11"); 378 if (entry != caller_registers.end()) { 379 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S11; 380 frame->context.s11 = entry->second; 381 } else if (last_frame->context_validity & 382 StackFrameRISCV::CONTEXT_VALID_S11) { 383 // Since the register is callee-saves, assume the callee 384 // has not yet changed it. 385 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_S11; 386 frame->context.s11 = last_frame->context.s11; 387 } 388 entry = caller_registers.find("t3"); 389 if (entry != caller_registers.end()) { 390 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T3; 391 frame->context.t3 = entry->second; 392 } 393 entry = caller_registers.find("t4"); 394 if (entry != caller_registers.end()) { 395 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T4; 396 frame->context.t4 = entry->second; 397 } 398 entry = caller_registers.find("t5"); 399 if (entry != caller_registers.end()) { 400 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T5; 401 frame->context.t5 = entry->second; 402 } 403 entry = caller_registers.find("t6"); 404 if (entry != caller_registers.end()) { 405 frame->context_validity |= StackFrameRISCV::CONTEXT_VALID_T6; 406 frame->context.t6 = entry->second; 407 } 408 409 // If we didn't recover the PC and the SP, then the frame isn't very useful. 410 static const uint64_t essentials = (StackFrameRISCV::CONTEXT_VALID_SP 411 | StackFrameRISCV::CONTEXT_VALID_PC); 412 if ((frame->context_validity & essentials) != essentials) 413 return NULL; 414 415 frame->trust = StackFrame::FRAME_TRUST_CFI; 416 return frame.release(); 417 } 418 419 StackFrameRISCV* StackwalkerRISCV::GetCallerByStackScan( 420 const vector<StackFrame*>& frames) { 421 StackFrameRISCV* last_frame = 422 static_cast<StackFrameRISCV*>(frames.back()); 423 uint32_t last_sp = last_frame->context.sp; 424 uint32_t caller_sp, caller_pc; 425 426 if (!ScanForReturnAddress(last_sp, &caller_sp, &caller_pc, 427 last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { 428 // No plausible return address was found. 429 return NULL; 430 } 431 432 // ScanForReturnAddress found a reasonable return address. Advance 433 // sp to the location above the one where the return address was 434 // found. 435 caller_sp += 4; 436 437 // Create a new stack frame (ownership will be transferred to the caller) 438 // and fill it in. 439 StackFrameRISCV* frame = new StackFrameRISCV(); 440 441 frame->trust = StackFrame::FRAME_TRUST_SCAN; 442 frame->context = last_frame->context; 443 frame->context.pc = caller_pc; 444 frame->context.sp = caller_sp; 445 frame->context_validity = StackFrameRISCV::CONTEXT_VALID_PC | 446 StackFrameRISCV::CONTEXT_VALID_SP; 447 448 return frame; 449 } 450 451 StackFrameRISCV* StackwalkerRISCV::GetCallerByFramePointer( 452 const vector<StackFrame*>& frames) { 453 StackFrameRISCV* last_frame = 454 static_cast<StackFrameRISCV*>(frames.back()); 455 456 uint32_t last_fp = last_frame->context.s0; 457 458 uint32_t caller_fp = 0; 459 if (last_fp && !memory_->GetMemoryAtAddress(last_fp, &caller_fp)) { 460 BPLOG(ERROR) << "Unable to read caller_fp from last_fp: 0x" 461 << std::hex << last_fp; 462 return NULL; 463 } 464 465 uint32_t caller_ra = 0; 466 if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 4, &caller_ra)) { 467 BPLOG(ERROR) << "Unable to read caller_ra from last_fp + 4: 0x" 468 << std::hex << (last_fp + 4); 469 return NULL; 470 } 471 472 uint32_t caller_sp = last_fp ? last_fp + 8 : last_frame->context.s0; 473 474 // Create a new stack frame (ownership will be transferred to the caller) 475 // and fill it in. 476 StackFrameRISCV* frame = new StackFrameRISCV(); 477 478 frame->trust = StackFrame::FRAME_TRUST_FP; 479 frame->context = last_frame->context; 480 frame->context.s0 = caller_fp; 481 frame->context.sp = caller_sp; 482 frame->context.pc = last_frame->context.ra; 483 frame->context.ra = caller_ra; 484 frame->context_validity = StackFrameRISCV::CONTEXT_VALID_PC | 485 StackFrameRISCV::CONTEXT_VALID_RA | 486 StackFrameRISCV::CONTEXT_VALID_S0 | 487 StackFrameRISCV::CONTEXT_VALID_SP; 488 return frame; 489 } 490 491 StackFrame* StackwalkerRISCV::GetCallerFrame(const CallStack* stack, 492 bool stack_scan_allowed) { 493 if (!memory_ || !stack) { 494 BPLOG(ERROR) << "Can't get caller frame without memory or stack"; 495 return NULL; 496 } 497 498 const vector<StackFrame*>& frames = *stack->frames(); 499 StackFrameRISCV* last_frame = 500 static_cast<StackFrameRISCV*>(frames.back()); 501 scoped_ptr<StackFrameRISCV> frame; 502 503 // Try to recover caller information from CFI. 504 scoped_ptr<CFIFrameInfo> cfi_frame_info( 505 frame_symbolizer_->FindCFIFrameInfo(last_frame)); 506 if (cfi_frame_info.get()) 507 frame.reset(GetCallerByCFIFrameInfo(frames, cfi_frame_info.get())); 508 509 // If CFI failed, or there wasn't CFI available, fall back to frame pointer. 510 if (!frame.get()) 511 frame.reset(GetCallerByFramePointer(frames)); 512 513 // If everything failed, fall back to stack scanning. 514 if (stack_scan_allowed && !frame.get()) 515 frame.reset(GetCallerByStackScan(frames)); 516 517 // If nothing worked, tell the caller. 518 if (!frame.get()) 519 return NULL; 520 521 // Should we terminate the stack walk? (end-of-stack or broken invariant) 522 if (TerminateWalk(frame->context.pc, frame->context.sp, 523 last_frame->context.sp, 524 last_frame->trust == StackFrame::FRAME_TRUST_CONTEXT)) { 525 return NULL; 526 } 527 528 // The new frame's context's PC is the return address, which is one 529 // instruction past the instruction that caused us to arrive at the callee. 530 // RISCV instructions have a uniform 4-byte encoding, so subtracting 4 off 531 // the return address gets back to the beginning of the call instruction. 532 // Callers that require the exact return address value may access 533 // frame->context.pc. 534 frame->instruction = frame->context.pc - 4; 535 536 return frame.release(); 537 } 538 539 } // namespace google_breakpad