Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp =================================================================== --- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -24,6 +24,7 @@ #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" @@ -460,6 +461,36 @@ } } +static bool HandlePPC64LocalEntryPoint(Thread &thread, bool stop, Symbol *sym, + ThreadPlanSP &thread_plan_sp) { + Target &target = thread.GetProcess()->GetTarget(); + if (target.GetArchitecture().GetMachine() != llvm::Triple::ppc64le) + return false; + + ConstString sym_name = sym->GetMangled().GetMangledName(); + if (!sym_name) + return false; + + lldb::addr_t current_address = thread.GetRegisterContext()->GetPC(0); + lldb::addr_t gep_addr = sym->GetLoadAddress(&target); + if (current_address == gep_addr) + return false; + + const ModuleList &images = target.GetImages(); + SymbolContextList target_symbols; + images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeLocal, target_symbols); + if (target_symbols.GetSize() != 1) + return false; + Symbol *lep = target_symbols[0].symbol; + + if (current_address != lep->GetLoadAddress(&target)) + return false; + + std::vector addrs = {gep_addr + sym->GetPrologueByteSize()}; + thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop)); + return true; +} + ThreadPlanSP DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) { @@ -469,6 +500,9 @@ const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol); Symbol *sym = context.symbol; + if (HandlePPC64LocalEntryPoint(thread, stop, sym, thread_plan_sp)) + return thread_plan_sp; + if (sym == NULL || !sym->IsTrampoline()) return thread_plan_sp; Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2377,6 +2377,34 @@ bool symbol_size_valid = symbol.st_size != 0 || symbol.getType() != STT_FUNC; + // PPC64: create an extra symbol for functions with local entry points. + const llvm::Triple::ArchType llvm_arch = arch.GetMachine(); + if (llvm_arch == llvm::Triple::ppc64 || + llvm_arch == llvm::Triple::ppc64le) { + int64_t loffs = llvm::ELF::decodePPC64LocalEntryOffset(symbol.st_other); + if (loffs) { + Symbol lep(i + start_id, // Symbol table index + symbol_name, // symbol name. + is_mangled, // is the symbol name mangled? + eSymbolTypeLocal, // Type of this symbol + // (trampoline types can't be looked up by + // name) + false, // Is this globally visible? + false, // Is this symbol debug info? + true, // Is this symbol a trampoline? + true, // Is this symbol artificial? + symbol_section_sp, // Section in which this symbol + // is defined or null. + symbol_value + loffs, // Offset in section or symbol value. + 0, // Size in bytes of this symbol. + false, // Size is valid + false, // Contains linker annotations? + 0); // Symbol flags. + + symtab->AddSymbol(lep); + } + } + Symbol dc_symbol( i + start_id, // ID is the original symbol table index. mangled,