docs: def _arm_track_lr_on_stack(self, addr, irsb, function):
          """
          At the beginning of the basic block, we check if the first instruction stores the LR register onto the stack.
          If it does, we calculate the offset of that store, and record the offset in function.info.
  
          For instance, here is the disassembly of a THUMB mode function:
  
          000007E4  STR.W           LR, [SP,#var_4]!
          000007E8  MOV             R2, R1
          000007EA  SUB             SP, SP, #0xC
          000007EC  MOVS            R1, #0
          ...
          00000800  ADD             SP, SP, #0xC
          00000802  LDR.W           PC, [SP+4+var_4],#4
  
          The very last basic block has a jumpkind of Ijk_Boring, which is because VEX cannot do such complicated analysis
          to determine the real jumpkind.
  
          As we can see, instruction 7e4h stores LR at [sp-4], and at the end of this function, instruction 802 loads LR
          from [sp], then increments sp by 4. We execute the first instruction, and track the following things:
          - if the value from register LR is stored onto the stack.
          - the difference between the offset of the LR store on stack, and the SP after the store.
  
          If at the end of the function, the LR is read out from the stack at the exact same stack offset, we will change
          the jumpkind of the final IRSB to Ijk_Ret.
  
          This method can be enabled by setting "ret_jumpkind_heuristics", which is an architecture-specific option on
          ARM, to True.
  
          :param int addr: Address of the basic block.
          :param pyvex.IRSB irsb: The basic block object.
          :param Function function: The function instance.
          :return: None
          """
  
          if irsb.statements is None:
              return
  
          if 'lr_saved_on_stack' in function.info:
              return
  
          # if it does, we log it down to the Function object.
          lr_offset = self.project.arch.registers['lr'][0]
          sp_offset = self.project.arch.sp_offset
          initial_sp = 0x7fff0000
          initial_lr = 0xabcdef
          tmps = {}
  
          # pylint:disable=too-many-nested-blocks
          for stmt in irsb.statements:
              if isinstance(stmt, pyvex.IRStmt.IMark):
                  if stmt.addr + stmt.delta != addr:
                      break
              elif isinstance(stmt, pyvex.IRStmt.WrTmp):
                  data = stmt.data
                  if isinstance(data, pyvex.IRExpr.Get):
                      if data.offset == sp_offset:
                          tmps[stmt.tmp] = initial_sp
                      elif data.offset == lr_offset:
                          tmps[stmt.tmp] = initial_lr
                  elif isinstance(data, pyvex.IRExpr.Binop):
                      if data.op == 'Iop_Sub32':
                          arg0, arg1 = data.args
                          if isinstance(arg0, pyvex.IRExpr.RdTmp) and isinstance(arg1, pyvex.IRExpr.Const):
                              if arg0.tmp in tmps:
                                  tmps[stmt.tmp] = tmps[arg0.tmp] - arg1.con.value
  
              elif isinstance(stmt, (pyvex.IRStmt.Store, pyvex.IRStmt.StoreG)):
                  data = stmt.data
                  storing_lr = False
                  if isinstance(data, pyvex.IRExpr.RdTmp):
                      if data.tmp in tmps:
                          val = tmps[data.tmp]
                          if val == initial_lr:
                              # we are storing LR to somewhere
                              storing_lr = True
                  if storing_lr:
                      if isinstance(stmt.addr, pyvex.IRExpr.RdTmp):
                          if stmt.addr.tmp in tmps:
                              storing_addr = tmps[stmt.addr.tmp]
  
                              function.info['lr_saved_on_stack'] = True
                              function.info['lr_on_stack_offset'] = storing_addr - initial_sp
                              break
  
          if 'lr_saved_on_stack' not in function.info:
              function.info['lr_saved_on_stack'] = False