/ src / processor / stackwalker_riscv64.cc
stackwalker_riscv64.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_riscv64.cc: riscv64-specific stackwalker.
 30   *
 31   * See stackwalker_riscv64.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_riscv64.h"
 49  
 50  namespace google_breakpad {
 51  
 52  StackwalkerRISCV64::StackwalkerRISCV64(const SystemInfo* system_info,
 53                                         const MDRawContextRISCV64* 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* StackwalkerRISCV64::GetContextFrame() {
 64    if (!context_) {
 65      BPLOG(ERROR) << "Can't get context frame without context";
 66      return NULL;
 67    }
 68  
 69    StackFrameRISCV64* frame = new StackFrameRISCV64();
 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  StackFrameRISCV64* StackwalkerRISCV64::GetCallerByCFIFrameInfo(
 80      const vector<StackFrame*>& frames,
 81      CFIFrameInfo* cfi_frame_info) {
 82    StackFrameRISCV64* last_frame =
 83        static_cast<StackFrameRISCV64*>(frames.back());
 84  
 85    // Populate a dictionary with the valid register values in last_frame.
 86    CFIFrameInfo::RegisterValueMap<uint64_t> callee_registers;
 87    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_PC)
 88      callee_registers["pc"] = last_frame->context.pc;
 89    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_RA)
 90      callee_registers["ra"] = last_frame->context.ra;
 91    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_SP)
 92      callee_registers["sp"] = last_frame->context.sp;
 93    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_GP)
 94      callee_registers["gp"] = last_frame->context.gp;
 95    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_TP)
 96      callee_registers["tp"] = last_frame->context.tp;
 97    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_T0)
 98      callee_registers["t0"] = last_frame->context.t0;
 99    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_T1)
100      callee_registers["t1"] = last_frame->context.t1;
101    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_T2)
102      callee_registers["t2"] = last_frame->context.t2;
103    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S0)
104      callee_registers["s0"] = last_frame->context.s0;
105    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S1)
106      callee_registers["s1"] = last_frame->context.s1;
107    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A0)
108      callee_registers["a0"] = last_frame->context.a0;
109    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A1)
110      callee_registers["a1"] = last_frame->context.a1;
111    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A2)
112      callee_registers["a2"] = last_frame->context.a2;
113    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A3)
114      callee_registers["a3"] = last_frame->context.a3;
115    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A4)
116      callee_registers["a4"] = last_frame->context.a4;
117    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A5)
118      callee_registers["a5"] = last_frame->context.a5;
119    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A6)
120      callee_registers["a6"] = last_frame->context.a6;
121    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_A7)
122      callee_registers["a7"] = last_frame->context.a7;
123    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S2)
124      callee_registers["s2"] = last_frame->context.s2;
125    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S3)
126      callee_registers["s3"] = last_frame->context.s3;
127    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S4)
128      callee_registers["s4"] = last_frame->context.s4;
129    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S5)
130      callee_registers["s5"] = last_frame->context.s5;
131    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S6)
132      callee_registers["s6"] = last_frame->context.s6;
133    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S7)
134      callee_registers["s7"] = last_frame->context.s7;
135    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S8)
136      callee_registers["s8"] = last_frame->context.s8;
137    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S9)
138      callee_registers["s9"] = last_frame->context.s9;
139    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S10)
140      callee_registers["s10"] = last_frame->context.s10;
141    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_S11)
142      callee_registers["s11"] = last_frame->context.s11;
143    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_T3)
144      callee_registers["t3"] = last_frame->context.t3;
145    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_T4)
146      callee_registers["t4"] = last_frame->context.t4;
147    if (last_frame->context_validity & StackFrameRISCV64::CONTEXT_VALID_T5)
148      callee_registers["t5"] = last_frame->context.t5;
149    if (last_frame->context_validity & StackFrameRISCV64::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<uint64_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<uint64_t>::iterator entry;
161    scoped_ptr<StackFrameRISCV64> frame(new StackFrameRISCV64());
162    entry = caller_registers.find("pc");
163    if (entry != caller_registers.end()) {
164      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S0;
219      frame->context.s0 = entry->second;
220    } else if (last_frame->context_validity &
221               StackFrameRISCV64::CONTEXT_VALID_S0) {
222      // Since the register is callee-saves, assume the callee
223      // has not yet changed it.
224      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S1;
230      frame->context.s1 = entry->second;
231    } else if (last_frame->context_validity &
232               StackFrameRISCV64::CONTEXT_VALID_S1) {
233      // Since the register is callee-saves, assume the callee
234      // has not yet changed it.
235      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S2;
281      frame->context.s2 = entry->second;
282    } else if (last_frame->context_validity &
283               StackFrameRISCV64::CONTEXT_VALID_S2) {
284      // Since the register is callee-saves, assume the callee
285      // has not yet changed it.
286      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S3;
292      frame->context.s3 = entry->second;
293    } else if (last_frame->context_validity &
294               StackFrameRISCV64::CONTEXT_VALID_S3) {
295      // Since the register is callee-saves, assume the callee
296      // has not yet changed it.
297      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S4;
303      frame->context.s4 = entry->second;
304    } else if (last_frame->context_validity &
305               StackFrameRISCV64::CONTEXT_VALID_S4) {
306      // Since the register is callee-saves, assume the callee
307      // has not yet changed it.
308      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S5;
314      frame->context.s5 = entry->second;
315    } else if (last_frame->context_validity &
316               StackFrameRISCV64::CONTEXT_VALID_S5) {
317      // Since the register is callee-saves, assume the callee
318      // has not yet changed it.
319      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S6;
325      frame->context.s6 = entry->second;
326    } else if (last_frame->context_validity &
327               StackFrameRISCV64::CONTEXT_VALID_S6) {
328      // Since the register is callee-saves, assume the callee
329      // has not yet changed it.
330      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S7;
336      frame->context.s7 = entry->second;
337    } else if (last_frame->context_validity &
338               StackFrameRISCV64::CONTEXT_VALID_S7) {
339      // Since the register is callee-saves, assume the callee
340      // has not yet changed it.
341      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S8;
347      frame->context.s8 = entry->second;
348    } else if (last_frame->context_validity &
349               StackFrameRISCV64::CONTEXT_VALID_S8) {
350      // Since the register is callee-saves, assume the callee
351      // has not yet changed it.
352      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S9;
358      frame->context.s9 = entry->second;
359    } else if (last_frame->context_validity &
360               StackFrameRISCV64::CONTEXT_VALID_S9) {
361      // Since the register is callee-saves, assume the callee
362      // has not yet changed it.
363      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S10;
369      frame->context.s10 = entry->second;
370    } else if (last_frame->context_validity &
371               StackFrameRISCV64::CONTEXT_VALID_S10) {
372      // Since the register is callee-saves, assume the callee
373      // has not yet changed it.
374      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::CONTEXT_VALID_S11;
380      frame->context.s11 = entry->second;
381    } else if (last_frame->context_validity &
382               StackFrameRISCV64::CONTEXT_VALID_S11) {
383      // Since the register is callee-saves, assume the callee
384      // has not yet changed it.
385      frame->context_validity |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 |= StackFrameRISCV64::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 = (StackFrameRISCV64::CONTEXT_VALID_SP
411                                        | StackFrameRISCV64::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  StackFrameRISCV64* StackwalkerRISCV64::GetCallerByStackScan(
420      const vector<StackFrame*>& frames) {
421    StackFrameRISCV64* last_frame =
422        static_cast<StackFrameRISCV64*>(frames.back());
423    uint64_t last_sp = last_frame->context.sp;
424    uint64_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 += 8;
436  
437    // Create a new stack frame (ownership will be transferred to the caller)
438    // and fill it in.
439    StackFrameRISCV64* frame = new StackFrameRISCV64();
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 = StackFrameRISCV64::CONTEXT_VALID_PC |
446                              StackFrameRISCV64::CONTEXT_VALID_SP;
447  
448    return frame;
449  }
450  
451  StackFrameRISCV64* StackwalkerRISCV64::GetCallerByFramePointer(
452      const vector<StackFrame*>& frames) {
453    StackFrameRISCV64* last_frame =
454        static_cast<StackFrameRISCV64*>(frames.back());
455  
456    uint64_t last_fp = last_frame->context.s0;
457  
458    uint64_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    uint64_t caller_ra = 0;
466    if (last_fp && !memory_->GetMemoryAtAddress(last_fp + 8, &caller_ra)) {
467      BPLOG(ERROR) << "Unable to read caller_ra from last_fp + 8: 0x"
468                   << std::hex << (last_fp + 8);
469      return NULL;
470    }
471  
472    uint64_t caller_sp = last_fp ? last_fp + 16 : last_frame->context.s0;
473  
474    // Create a new stack frame (ownership will be transferred to the caller)
475    // and fill it in.
476    StackFrameRISCV64* frame = new StackFrameRISCV64();
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 = StackFrameRISCV64::CONTEXT_VALID_PC |
485                              StackFrameRISCV64::CONTEXT_VALID_RA |
486                              StackFrameRISCV64::CONTEXT_VALID_S0 |
487                              StackFrameRISCV64::CONTEXT_VALID_SP;
488    return frame;
489  }
490  
491  StackFrame* StackwalkerRISCV64::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    StackFrameRISCV64* last_frame =
500        static_cast<StackFrameRISCV64*>(frames.back());
501    scoped_ptr<StackFrameRISCV64> 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