[libunwind] Factor out getInfoFromFdeCie. NFCI.

Differential Revision: https://reviews.llvm.org/D86255

GitOrigin-RevId: 3071d5ffba2337174f95f984bc1603a2be8b797d
diff --git a/src/UnwindCursor.hpp b/src/UnwindCursor.hpp
index 5491336..e6a3676 100644
--- a/src/UnwindCursor.hpp
+++ b/src/UnwindCursor.hpp
@@ -925,6 +925,9 @@
 #endif
 
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
+  bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
+                         const typename CFI_Parser<A>::CIE_Info &cieInfo,
+                         pint_t pc, uintptr_t dso_base);
   bool getInfoFromDwarfSection(pint_t pc, const UnwindInfoSections &sects,
                                             uint32_t fdeSectionOffsetHint=0);
   int stepWithDwarfFDE() {
@@ -1477,6 +1480,32 @@
 
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
 template <typename A, typename R>
+bool UnwindCursor<A, R>::getInfoFromFdeCie(
+    const typename CFI_Parser<A>::FDE_Info &fdeInfo,
+    const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc,
+    uintptr_t dso_base) {
+  typename CFI_Parser<A>::PrologInfo prolog;
+  if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
+                                          R::getArch(), &prolog)) {
+    // Save off parsed FDE info
+    _info.start_ip          = fdeInfo.pcStart;
+    _info.end_ip            = fdeInfo.pcEnd;
+    _info.lsda              = fdeInfo.lsda;
+    _info.handler           = cieInfo.personality;
+    // Some frameless functions need SP altered when resuming in function, so
+    // propagate spExtraArgSize.
+    _info.gp                = prolog.spExtraArgSize;
+    _info.flags             = 0;
+    _info.format            = dwarfEncoding();
+    _info.unwind_info       = fdeInfo.fdeStart;
+    _info.unwind_info_size  = static_cast<uint32_t>(fdeInfo.fdeLength);
+    _info.extra             = static_cast<unw_word_t>(dso_base);
+    return true;
+  }
+  return false;
+}
+
+template <typename A, typename R>
 bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
                                                 const UnwindInfoSections &sects,
                                                 uint32_t fdeSectionOffsetHint) {
@@ -1516,21 +1545,7 @@
                                       &fdeInfo, &cieInfo);
   }
   if (foundFDE) {
-    typename CFI_Parser<A>::PrologInfo prolog;
-    if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
-                                            R::getArch(), &prolog)) {
-      // Save off parsed FDE info
-      _info.start_ip          = fdeInfo.pcStart;
-      _info.end_ip            = fdeInfo.pcEnd;
-      _info.lsda              = fdeInfo.lsda;
-      _info.handler           = cieInfo.personality;
-      _info.gp                = prolog.spExtraArgSize;
-      _info.flags             = 0;
-      _info.format            = dwarfEncoding();
-      _info.unwind_info       = fdeInfo.fdeStart;
-      _info.unwind_info_size  = (uint32_t)fdeInfo.fdeLength;
-      _info.extra             = (unw_word_t) sects.dso_base;
-
+    if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {
       // Add to cache (to make next lookup faster) if we had no hint
       // and there was no index.
       if (!foundInCache && (fdeSectionOffsetHint == 0)) {
@@ -1932,58 +1947,24 @@
   // dynamically registered for it.
   pint_t cachedFDE = DwarfFDECache<A>::findFDE(0, pc);
   if (cachedFDE != 0) {
-    CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
-    CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
-    const char *msg = CFI_Parser<A>::decodeFDE(_addressSpace,
-                                                cachedFDE, &fdeInfo, &cieInfo);
-    if (msg == NULL) {
-      typename CFI_Parser<A>::PrologInfo prolog;
-      if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
-                                              pc, R::getArch(), &prolog)) {
-        // save off parsed FDE info
-        _info.start_ip         = fdeInfo.pcStart;
-        _info.end_ip           = fdeInfo.pcEnd;
-        _info.lsda             = fdeInfo.lsda;
-        _info.handler          = cieInfo.personality;
-        _info.gp               = prolog.spExtraArgSize;
-                                  // Some frameless functions need SP
-                                  // altered when resuming in function.
-        _info.flags            = 0;
-        _info.format           = dwarfEncoding();
-        _info.unwind_info      = fdeInfo.fdeStart;
-        _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
-        _info.extra            = 0;
+    typename CFI_Parser<A>::FDE_Info fdeInfo;
+    typename CFI_Parser<A>::CIE_Info cieInfo;
+    if (!CFI_Parser<A>::decodeFDE(_addressSpace, cachedFDE, &fdeInfo, &cieInfo))
+      if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
         return;
-      }
-    }
   }
 
   // Lastly, ask AddressSpace object about platform specific ways to locate
   // other FDEs.
   pint_t fde;
   if (_addressSpace.findOtherFDE(pc, fde)) {
-    CFI_Parser<LocalAddressSpace>::FDE_Info fdeInfo;
-    CFI_Parser<LocalAddressSpace>::CIE_Info cieInfo;
+    typename CFI_Parser<A>::FDE_Info fdeInfo;
+    typename CFI_Parser<A>::CIE_Info cieInfo;
     if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
       // Double check this FDE is for a function that includes the pc.
-      if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd)) {
-        typename CFI_Parser<A>::PrologInfo prolog;
-        if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo,
-                                                pc, R::getArch(), &prolog)) {
-          // save off parsed FDE info
-          _info.start_ip         = fdeInfo.pcStart;
-          _info.end_ip           = fdeInfo.pcEnd;
-          _info.lsda             = fdeInfo.lsda;
-          _info.handler          = cieInfo.personality;
-          _info.gp               = prolog.spExtraArgSize;
-          _info.flags            = 0;
-          _info.format           = dwarfEncoding();
-          _info.unwind_info      = fdeInfo.fdeStart;
-          _info.unwind_info_size = (uint32_t)fdeInfo.fdeLength;
-          _info.extra            = 0;
+      if ((fdeInfo.pcStart <= pc) && (pc < fdeInfo.pcEnd))
+        if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, 0))
           return;
-        }
-      }
     }
   }
 #endif // #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)