Function report

Linux Kernel

v5.5.9

Brick Technologies Co., Ltd

Source Code:arch\x86\kernel\unwind_orc.c Create Date:2022-07-28 08:51:05
Last Modify:2020-03-12 14:18:49 Copyright©Brick
home page Tree
Annotation kernel can get tool activityDownload SCCTChinese

Name:unwind_next_frame

Proto:bool unwind_next_frame(struct unwind_state *state)

Type:bool

Parameter:

TypeParameterName
struct unwind_state *state
383  orig_ip = ip , prev_sp = sp
384  prev_type = type
386  bool indirect = false
388  If unwind_done(state) Then Return false
392  Even if we don't have any preemption, we need preempt disable/enable* to be barriers, so that we don't have things like get_user/put_user* that can cause faults and scheduling migrate into our preempt-protected* region.()
395  If regs && ser_mode(regs) determines whether a register set came from user* mode Then Go to the_end
404  orc = orc_find(signal ? ip : ip - 1)
405  If Not orc Then
412  orc = Fake frame pointer entry -- used as a fallback for generated code
413  error = true
417  If sp_reg == The ORC_REG_* registers are base registers which are used to find other* registers on the stack Then
418  If Not end Then Go to err
421  Go to the_end
426  Case sp_reg == ORC_REG_SP
427  sp = sp + sp_offset
428  Break
430  Case sp_reg == ORC_REG_BP
431  sp = bp + sp_offset
432  Break
434  Case sp_reg == ORC_REG_SP_INDIRECT
435  sp = sp + sp_offset
436  indirect = true
437  Break
439  Case sp_reg == ORC_REG_BP_INDIRECT
440  sp = bp + sp_offset
441  indirect = true
442  Break
444  Case sp_reg == ORC_REG_R10
445  If Not regs || Not full_regs Then
446  orc_warn("missing regs for base reg R10 at ip %pB\n", (void * )ip)
448  Go to err
450  sp = r10
451  Break
453  Case sp_reg == ORC_REG_R13
454  If Not regs || Not full_regs Then
455  orc_warn("missing regs for base reg R13 at ip %pB\n", (void * )ip)
457  Go to err
459  sp = r13
460  Break
462  Case sp_reg == ORC_REG_DI
463  If Not regs || Not full_regs Then
464  orc_warn("missing regs for base reg DI at ip %pB\n", (void * )ip)
466  Go to err
468  sp = di
469  Break
471  Case sp_reg == ORC_REG_DX
472  If Not regs || Not full_regs Then
473  orc_warn("missing regs for base reg DX at ip %pB\n", (void * )ip)
475  Go to err
477  sp = dx
478  Break
480  Default
481  orc_warn("unknown SP base reg %d for ip %pB\n", sp_reg, (void * )ip)
483  Go to err
486  If indirect Then
487  If Not deref_stack_reg(state, sp, & sp) Then Go to err
494  ip_p = sp - sizeof(long)
496  If Not deref_stack_reg(state, ip_p, & ip) Then Go to err
499  ip = ftrace_graph_ret_addr(task, & graph_idx, ip, (void * )ip_p)
502  sp = sp
503  regs = NULL
504  signal = false
505  Break
507  Case type == ORC_TYPE_REGS
508  If Not deref_stack_regs(state, sp, & ip, & sp) Then
509  orc_warn("can't dereference registers at %p for ip %pB\n", (void * )sp, (void * )orig_ip)
511  Go to err
514  regs = sp
515  full_regs = true
516  signal = true
517  Break
519  Case type == ORC_TYPE_REGS_IRET
520  If Not deref_stack_iret_regs(state, sp, & ip, & sp) Then
521  orc_warn("can't dereference iret registers at %p for ip %pB\n", (void * )sp, (void * )orig_ip)
523  Go to err
527  full_regs = false
528  signal = true
529  Break
531  Default
532  orc_warn("unknown .orc_unwind entry type %d for ip %pB\n", type, (void * )orig_ip)
534  Break
540  If regs && full_regs Then bp = bp
542  Break
544  Case bp_reg == ORC_REG_PREV_SP
545  If Not deref_stack_reg(state, sp + bp_offset, & bp) Then Go to err
547  Break
549  Case bp_reg == ORC_REG_BP
550  If Not deref_stack_reg(state, bp + bp_offset, & bp) Then Go to err
552  Break
554  Default
555  orc_warn("unknown BP base reg %d for ip %pB\n", bp_reg, (void * )orig_ip)
557  Go to err
561  If type == prev_type && on_stack( & stack_info, (void * )sp, sizeof(long)) && sp <= prev_sp Then
564  orc_warn("stack going in the wrong direction? ip=%pB\n", (void * )orig_ip)
566  Go to err
569  preempt_enable()
570  Return true
572  err :
573  error = true
575  the_end :
576  preempt_enable()
578  Return false