================
@@ -868,6 +868,41 @@ RegisterContextUnwind::GetFullUnwindPlanForFrame() {
     return arch_default_unwind_plan_sp;
   }
 
+  // Function outlining is a clang feature where common blocks of instructions
+  // from separate functions can be put in a separate utility function, and
+  // the original functions call into the utility function to execute them,
+  // resulting in fewer bytes used for the code section overall.
+  //
+  // The call to the OUTLINED_FUNCTION may not be a normal ABI call (e.g.
+  // on RISCV it might be called `jal t0, OUTLINED_FUNCTION_<nn>` putting the
+  // return address in a temporary register instead of $ra).  Tthe unwind
+  // instructions in eh_frame/debug_frame are not correct today for an
+  // OUTLINED_FUNCTION, even when a normal ABI call is made.
+  // Clang does not insert CFI directives in the OUTLINED_FUNCTION so it
+  // will look like a frameless function that does nothing beyond its initial
+  // unwind state.
+  //
+  // A function may outline its prologue, mid-function block of instructions,
+  // or its epilogue.  If a function's prologue is outlined, the unwind
+  // instructions (eh_frame/debug_frame/lldb's instruction analysis) for the
+  // original function are incorrect and cannot be trusted.
+  //
+  // If we are in an OUTLINED_FUNCTION in a backtrace, distrust all sources
+  // of unwind information and use the architectural default unwind plan
+  // instead.  We may miss the caller stack frame in the backtrace, but it
+  // will work more reliably than any other method.
+  if (m_sym_ctx_valid && arch_default_unwind_plan_sp) {
+    const char *name = GetSymbolOrFunctionName(m_sym_ctx).AsCString("");
+    if (!strncmp(name, "OUTLINED_FUNCTION_",
+                 sizeof("OUTLINED_FUNCTION_") - 1)) {
----------------
DavidSpickett wrote:

I looked at what GCC does, I'm not sure it has an outliner the same as llvm but 
it does have function splitting and that uses `<...>.part.<number>` naming, and 
includes CFI directives.

My point being: looking at the function name isn't ideal but I don't see an 
alternative and it does not clash with gcc as far as I can tell.

I don't quite understand why we have to have the special case though. If we are 
in a function without CFI, don't we just fall back to some other plan?

Or is that your point. Where clang inserts zero CFI, that's fine, we fall back. 
When it corrupts the CFI, that's the case you're handling here.

https://github.com/llvm/llvm-project/pull/204500
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to