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/4] 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/4] 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/4] 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; } } } >From 25c3eefe80778940d141af28fd9455eb0baee2ba Mon Sep 17 00:00:00 2001 From: ShengYi Hung <[email protected]> Date: Thu, 16 Jul 2026 22:42:37 +0800 Subject: [PATCH 4/4] fixup! Support Re-export Symbol for FunctionCall --- .../Process/Utility/InferiorCallPOSIX.cpp | 52 +++++++++---------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp index f11594f2327d1..d4d79e712a83d 100644 --- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp +++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp @@ -165,33 +165,31 @@ 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) { - { - EvaluateExpressionOptions options; - options.SetStopOthers(true); - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); - options.SetTryAllThreads(true); - options.SetDebug(false); - options.SetTimeout(process->GetUtilityExpressionTimeout()); - options.SetTrapExceptions(false); - - 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( - *thread, munmap_addr, CompilerType(), 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) { - return true; - } + EvaluateExpressionOptions options; + options.SetStopOthers(true); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetTryAllThreads(true); + options.SetDebug(false); + options.SetTimeout(process->GetUtilityExpressionTimeout()); + options.SetTrapExceptions(false); + + 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( + *thread, munmap_addr, CompilerType(), 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) { + return true; } } } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
