https://github.com/aokblast updated 
https://github.com/llvm/llvm-project/pull/208998

>From 0b85e1e9f569820064e6cbf999a9853e7bdb3f8b Mon Sep 17 00:00:00 2001
From: ShengYi Hung <[email protected]>
Date: Sat, 11 Jul 2026 19:11:57 +0800
Subject: [PATCH 1/3] Support Re-export Symbol for FunctionCall

A symbol can be a stub that is re-exported to another library. For
example, ELF can specify an auxiliary library and emit a zero-sized
symbol in the symbol table. This can cause expression evaluation to
resolve the stub instead of the actual function. Fix this by resolving
re-exported symbols to their actual addressed.
---
 .../Process/Utility/InferiorCallPOSIX.cpp     | 34 +++++++++++++++----
 1 file changed, 28 insertions(+), 6 deletions(-)

diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp 
b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 5226b9bbe7c78..f190b589ad704 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -33,6 +33,30 @@
 using namespace lldb;
 using namespace lldb_private;
 
+/// Pick a call target from \p sc_list.  Re-exported symbols have no code of
+/// their own and are resolved through the library that actually defines
+/// them, mirroring what the dynamic linker does.
+static Address GetCallableAddress(Target &target,
+                                  const SymbolContextList &sc_list) {
+  const uint32_t count = sc_list.GetSize();
+  for (uint32_t i = 0; i < count; ++i) {
+    SymbolContext sc;
+    if (!sc_list.GetContextAtIndex(i, sc))
+      continue;
+    if (sc.symbol && sc.symbol->GetType() == eSymbolTypeReExported) {
+      // Pass the containing module so all of its re-exported libraries
+      // (e.g. an ELF filter library's filtees) are searched in order.
+      if (Symbol *actual =
+              sc.symbol->ResolveReExportedSymbol(target, sc.module_sp))
+        return actual->GetAddress();
+      // Unresolvable re-export: not callable.
+      continue;
+    }
+    return sc.GetFunctionOrSymbolAddress();
+  }
+  return Address();
+}
+
 bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
                                     addr_t addr, addr_t length, unsigned prot,
                                     unsigned flags, addr_t fd, addr_t offset) {
@@ -50,8 +74,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t 
&allocated_addr,
       ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list);
   const uint32_t count = sc_list.GetSize();
   if (count > 0) {
-    SymbolContext sc;
-    if (sc_list.GetContextAtIndex(0, sc)) {
+    {
       EvaluateExpressionOptions options;
       options.SetStopOthers(true);
       options.SetUnwindOnError(true);
@@ -74,7 +97,7 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t 
&allocated_addr,
           prot_arg |= PROT_WRITE;
       }
 
-      Address mmap_addr = sc.GetFunctionOrSymbolAddress();
+      Address mmap_addr = GetCallableAddress(process->GetTarget(), sc_list);
       if (mmap_addr.IsValid()) {
         auto type_system_or_err =
             process->GetTarget().GetScratchTypeSystemForLanguage(
@@ -142,8 +165,7 @@ bool lldb_private::InferiorCallMunmap(Process *process, 
addr_t addr,
       ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list);
   const uint32_t count = sc_list.GetSize();
   if (count > 0) {
-    SymbolContext sc;
-    if (sc_list.GetContextAtIndex(0, sc)) {
+    {
       EvaluateExpressionOptions options;
       options.SetStopOthers(true);
       options.SetUnwindOnError(true);
@@ -153,7 +175,7 @@ bool lldb_private::InferiorCallMunmap(Process *process, 
addr_t addr,
       options.SetTimeout(process->GetUtilityExpressionTimeout());
       options.SetTrapExceptions(false);
 
-      Address munmap_addr = sc.GetFunctionOrSymbolAddress();
+      Address munmap_addr = GetCallableAddress(process->GetTarget(), sc_list);
       if (munmap_addr.IsValid()) {
         lldb::addr_t args[] = {addr, length};
         lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(

>From cff87246629c8aeef17459c99d76b1f88c4a3486 Mon Sep 17 00:00:00 2001
From: ShengYi Hung <[email protected]>
Date: Tue, 14 Jul 2026 21:38:36 +0800
Subject: [PATCH 2/3] fixup! Support Re-export Symbol for FunctionCall

---
 .../Plugins/Process/Utility/InferiorCallPOSIX.cpp | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp 
b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index f190b589ad704..dbc53ce5fcee6 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -33,9 +33,10 @@
 using namespace lldb;
 using namespace lldb_private;
 
-/// Pick a call target from \p sc_list.  Re-exported symbols have no code of
-/// their own and are resolved through the library that actually defines
-/// them, mirroring what the dynamic linker does.
+/// Pick a call target from \p sc_list.  A symbol from an ELF filter/auxiliary
+/// library is resolved through its filtee(s) first, falling back to its own
+/// definition only if none of them provide it, mirroring what the dynamic
+/// linker does.
 static Address GetCallableAddress(Target &target,
                                   const SymbolContextList &sc_list) {
   const uint32_t count = sc_list.GetSize();
@@ -43,14 +44,16 @@ static Address GetCallableAddress(Target &target,
     SymbolContext sc;
     if (!sc_list.GetContextAtIndex(i, sc))
       continue;
-    if (sc.symbol && sc.symbol->GetType() == eSymbolTypeReExported) {
+    if (sc.symbol) {
       // Pass the containing module so all of its re-exported libraries
       // (e.g. an ELF filter library's filtees) are searched in order.
       if (Symbol *actual =
               sc.symbol->ResolveReExportedSymbol(target, sc.module_sp))
         return actual->GetAddress();
-      // Unresolvable re-export: not callable.
-      continue;
+      // A pure re-export placeholder with no filtee providing a definition
+      // has no code of its own and isn't callable.
+      if (sc.symbol->GetType() == eSymbolTypeReExported)
+        continue;
     }
     return sc.GetFunctionOrSymbolAddress();
   }

>From 66dc68d21562acbe70b4ae035e46e121603f125c Mon Sep 17 00:00:00 2001
From: ShengYi Hung <[email protected]>
Date: Tue, 14 Jul 2026 22:31:57 +0800
Subject: [PATCH 3/3] fixup! Support Re-export Symbol for FunctionCall

---
 .../Process/Utility/InferiorCallPOSIX.cpp     | 123 +++++++++---------
 1 file changed, 60 insertions(+), 63 deletions(-)

diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp 
b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index dbc53ce5fcee6..f11594f2327d1 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -77,72 +77,69 @@ bool lldb_private::InferiorCallMmap(Process *process, 
addr_t &allocated_addr,
       ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list);
   const uint32_t count = sc_list.GetSize();
   if (count > 0) {
-    {
-      EvaluateExpressionOptions options;
-      options.SetStopOthers(true);
-      options.SetUnwindOnError(true);
-      options.SetIgnoreBreakpoints(true);
-      options.SetTryAllThreads(true);
-      options.SetDebug(false);
-      options.SetTimeout(process->GetUtilityExpressionTimeout());
-      options.SetTrapExceptions(false);
+    EvaluateExpressionOptions options;
+    options.SetStopOthers(true);
+    options.SetUnwindOnError(true);
+    options.SetIgnoreBreakpoints(true);
+    options.SetTryAllThreads(true);
+    options.SetDebug(false);
+    options.SetTimeout(process->GetUtilityExpressionTimeout());
+    options.SetTrapExceptions(false);
+
+    addr_t prot_arg;
+    if (prot == eMmapProtNone)
+      prot_arg = PROT_NONE;
+    else {
+      prot_arg = 0;
+      if (prot & eMmapProtExec)
+        prot_arg |= PROT_EXEC;
+      if (prot & eMmapProtRead)
+        prot_arg |= PROT_READ;
+      if (prot & eMmapProtWrite)
+        prot_arg |= PROT_WRITE;
+    }
 
-      addr_t prot_arg;
-      if (prot == eMmapProtNone)
-        prot_arg = PROT_NONE;
-      else {
-        prot_arg = 0;
-        if (prot & eMmapProtExec)
-          prot_arg |= PROT_EXEC;
-        if (prot & eMmapProtRead)
-          prot_arg |= PROT_READ;
-        if (prot & eMmapProtWrite)
-          prot_arg |= PROT_WRITE;
+    Address mmap_addr = GetCallableAddress(process->GetTarget(), sc_list);
+    if (mmap_addr.IsValid()) {
+      auto type_system_or_err =
+          process->GetTarget().GetScratchTypeSystemForLanguage(eLanguageTypeC);
+      if (!type_system_or_err) {
+        llvm::consumeError(type_system_or_err.takeError());
+        return false;
       }
-
-      Address mmap_addr = GetCallableAddress(process->GetTarget(), sc_list);
-      if (mmap_addr.IsValid()) {
-        auto type_system_or_err =
-            process->GetTarget().GetScratchTypeSystemForLanguage(
-                eLanguageTypeC);
-        if (!type_system_or_err) {
-          llvm::consumeError(type_system_or_err.takeError());
-          return false;
-        }
-        auto ts = *type_system_or_err;
-        if (!ts)
-          return false;
-        CompilerType void_ptr_type =
-            ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
-        const ArchSpec arch = process->GetTarget().GetArchitecture();
-        MmapArgList args =
-            process->GetTarget().GetPlatform()->GetMmapArgumentList(
-                arch, addr, length, prot_arg, flags, fd, offset);
-        lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
-            *thread, mmap_addr, void_ptr_type, args, options));
-        if (call_plan_sp) {
-          DiagnosticManager diagnostics;
-
-          StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
-          if (frame) {
-            ExecutionContext exe_ctx;
-            frame->CalculateExecutionContext(exe_ctx);
-            ExpressionResults result = process->RunThreadPlan(
-                exe_ctx, call_plan_sp, options, diagnostics);
-            if (result == eExpressionCompleted) {
-
-              allocated_addr =
-                  call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
-                      LLDB_INVALID_ADDRESS);
-              if (process->GetAddressByteSize() == 4) {
-                if (allocated_addr == UINT32_MAX)
-                  return false;
-              } else if (process->GetAddressByteSize() == 8) {
-                if (allocated_addr == UINT64_MAX)
-                  return false;
-              }
-              return true;
+      auto ts = *type_system_or_err;
+      if (!ts)
+        return false;
+      CompilerType void_ptr_type =
+          ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
+      const ArchSpec arch = process->GetTarget().GetArchitecture();
+      MmapArgList args =
+          process->GetTarget().GetPlatform()->GetMmapArgumentList(
+              arch, addr, length, prot_arg, flags, fd, offset);
+      lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
+          *thread, mmap_addr, void_ptr_type, args, options));
+      if (call_plan_sp) {
+        DiagnosticManager diagnostics;
+
+        StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+        if (frame) {
+          ExecutionContext exe_ctx;
+          frame->CalculateExecutionContext(exe_ctx);
+          ExpressionResults result = process->RunThreadPlan(
+              exe_ctx, call_plan_sp, options, diagnostics);
+          if (result == eExpressionCompleted) {
+
+            allocated_addr =
+                call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
+                    LLDB_INVALID_ADDRESS);
+            if (process->GetAddressByteSize() == 4) {
+              if (allocated_addr == UINT32_MAX)
+                return false;
+            } else if (process->GetAddressByteSize() == 8) {
+              if (allocated_addr == UINT64_MAX)
+                return false;
             }
+            return true;
           }
         }
       }

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to