ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, const lldb::DataBufferSP &data_sp, lldb::offset_t data_offset) : ModuleChild(module_sp), m_file(), // This file could be different from the original module's file m_type(eTypeInvalid), m_strata(eStrataInvalid), m_file_offset(file_offset), m_length(length), m_data(), m_unwind_table(*this), m_process_wp(), m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_ap(), m_symtab_ap(), m_synthetic_symbol_idx(0) { if (file_spec_ptr) m_file = *file_spec_ptr; if (data_sp) m_data.SetData(data_sp, data_offset, length); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); if (log) log->Printf("%p ObjectFile::ObjectFile() module = %p (%s), file = %s, " "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64, static_cast<void *>(this), static_cast<void *>(module_sp.get()), module_sp->GetSpecificationDescription().c_str(), m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset, m_length); }
ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, DataBufferSP& header_data_sp) : ModuleChild (module_sp), m_file (), m_type (eTypeInvalid), m_strata (eStrataInvalid), m_file_offset (0), m_length (0), m_data (), m_unwind_table (*this), m_process_wp (process_sp), m_memory_addr (header_addr), m_sections_ap (), m_symtab_ap (), m_symtab_unified_ap (), m_symtab_unified_revisionid (0) { if (header_data_sp) m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize()); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) { log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), process = %p, header_addr = 0x%" PRIx64, this, module_sp.get(), module_sp->GetSpecificationDescription().c_str(), process_sp.get(), m_memory_addr); } }
ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, DataBufferSP& header_data_sp) : ModuleChild (module_sp), m_file (), m_type (eTypeInvalid), m_strata (eStrataInvalid), m_offset (header_addr), m_length (0), m_data (), m_unwind_table (*this), m_process_wp (process_sp), m_memory_addr (header_addr) { if (header_data_sp) m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize()); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) { log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%llx\n", this, module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), process_sp.get(), m_offset); } }
ObjectFileSP ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, DataBufferSP &file_data_sp) { ObjectFileSP object_file_sp; if (module_sp) { Timer scoped_timer (__PRETTY_FUNCTION__, "ObjectFile::FindPlugin (module = %s/%s, process = %p, header_addr = 0x%llx)", module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), process_sp.get(), header_addr); uint32_t idx; // Check if this is a normal object file by iterating through // all object file plugin instances. ObjectFileCreateMemoryInstance create_callback; for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx) { object_file_sp.reset (create_callback(module_sp, file_data_sp, process_sp, header_addr)); if (object_file_sp.get()) return object_file_sp; } } // We didn't find it, so clear our shared pointer in case it // contains anything and return an empty shared pointer object_file_sp.reset(); return object_file_sp; }
bool AddressSanitizerRuntime::CheckIfRuntimeIsValid( const lldb::ModuleSP module_sp) { const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( ConstString("__asan_get_alloc_stack"), lldb::eSymbolTypeAny); return symbol != nullptr; }
ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const ProcessSP &process_sp, lldb::addr_t header_addr, DataBufferSP &data_sp) { ObjectFileSP object_file_sp; if (module_sp) { Timer scoped_timer(LLVM_PRETTY_FUNCTION, "ObjectFile::FindPlugin (module = " "%s, process = %p, header_addr = " "0x%" PRIx64 ")", module_sp->GetFileSpec().GetPath().c_str(), static_cast<void *>(process_sp.get()), header_addr); uint32_t idx; // Check if this is a normal object file by iterating through // all object file plugin instances. ObjectFileCreateMemoryInstance create_callback; for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != nullptr; ++idx) { object_file_sp.reset( create_callback(module_sp, data_sp, process_sp, header_addr)); if (object_file_sp.get()) return object_file_sp; } } // We didn't find it, so clear our shared pointer in case it // contains anything and return an empty shared pointer object_file_sp.reset(); return object_file_sp; }
static DWARFExpression MakeRegisterBasedLocationExpressionInternal( llvm::codeview::RegisterId reg, llvm::Optional<int32_t> relative_offset, lldb::ModuleSP module) { return MakeLocationExpressionInternal( module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { uint32_t reg_num = GetRegisterNumber( module->GetArchitecture().GetMachine(), reg, register_kind); if (reg_num == LLDB_INVALID_REGNUM) return false; if (reg_num > 31) { llvm::dwarf::LocationAtom base = relative_offset ? llvm::dwarf::DW_OP_bregx : llvm::dwarf::DW_OP_regx; stream.PutHex8(base); stream.PutULEB128(reg_num); } else { llvm::dwarf::LocationAtom base = relative_offset ? llvm::dwarf::DW_OP_breg0 : llvm::dwarf::DW_OP_reg0; stream.PutHex8(base + reg_num); } if (relative_offset) stream.PutSLEB128(*relative_offset); return true; }); }
ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, addr_t file_offset, addr_t file_size, DataBufferSP& file_data_sp) : ModuleChild (module_sp), m_file (), // This file could be different from the original module's file m_type (eTypeInvalid), m_strata (eStrataInvalid), m_offset (file_offset), m_length (file_size), m_data (), m_unwind_table (*this), m_process_wp(), m_memory_addr (LLDB_INVALID_ADDRESS) { if (file_spec_ptr) m_file = *file_spec_ptr; if (file_data_sp) m_data.SetData (file_data_sp, file_offset, file_size); LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) { if (m_file) { log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n", this, module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), m_file.GetDirectory().AsCString(), m_file.GetFilename().AsCString(), m_offset, m_length); } else { log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n", this, module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), m_offset, m_length); } } }
void VerifyLineEntry(lldb::ModuleSP module, const SymbolContext &sc, const FileSpec &spec, LineTable <, uint32_t line, lldb::addr_t addr) { LineEntry entry; Address address; EXPECT_TRUE(module->ResolveFileAddress(addr, address)); EXPECT_TRUE(lt.FindLineEntryByAddress(address, entry)); EXPECT_EQ(line, entry.line); EXPECT_EQ(address, entry.range.GetBaseAddress()); EXPECT_TRUE(FileSpecMatchesAsBaseOrFull(spec, entry.file)); }
bool PlatformDarwin::ModuleIsExcludedForNonModuleSpecificSearches (lldb_private::Target &target, const lldb::ModuleSP &module_sp) { if (!module_sp) return false; ObjectFile *obj_file = module_sp->GetObjectFile(); if (!obj_file) return false; ObjectFile::Type obj_type = obj_file->GetType(); if (obj_type == ObjectFile::eTypeDynamicLinker) return true; else return false; }
lldb::addr_t DynamicLoaderPOSIXDYLD::GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread) { auto it = m_loaded_modules.find (module); if (it == m_loaded_modules.end()) return LLDB_INVALID_ADDRESS; addr_t link_map = it->second; if (link_map == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; const DYLDRendezvous::ThreadInfo &metadata = m_rendezvous.GetThreadInfo(); if (!metadata.valid) return LLDB_INVALID_ADDRESS; // Get the thread pointer. addr_t tp = thread->GetThreadPointer (); if (tp == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; // Find the module's modid. int modid_size = 4; // FIXME(spucci): This isn't right for big-endian 64-bit int64_t modid = ReadUnsignedIntWithSizeInBytes (link_map + metadata.modid_offset, modid_size); if (modid == -1) return LLDB_INVALID_ADDRESS; // Lookup the DTV structure for this thread. addr_t dtv_ptr = tp + metadata.dtv_offset; addr_t dtv = ReadPointer (dtv_ptr); if (dtv == LLDB_INVALID_ADDRESS) return LLDB_INVALID_ADDRESS; // Find the TLS block for this module. addr_t dtv_slot = dtv + metadata.dtv_slot_size*modid; addr_t tls_block = ReadPointer (dtv_slot + metadata.tls_offset); Module *mod = module.get(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (log) log->Printf("DynamicLoaderPOSIXDYLD::Performed TLS lookup: " "module=%s, link_map=0x%" PRIx64 ", tp=0x%" PRIx64 ", modid=%" PRId64 ", tls_block=0x%" PRIx64 "\n", mod->GetObjectName().AsCString(""), link_map, tp, (int64_t)modid, tls_block); return tls_block; }
void DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (m_process == nullptr) return; auto &target = m_process->GetTarget (); const auto platform_sp = target.GetPlatform (); ProcessInstanceInfo process_info; if (!platform_sp->GetProcessInfo (m_process->GetID (), process_info)) { if (log) log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to get process info for pid %" PRIu64, __FUNCTION__, m_process->GetID ()); return; } if (log) log->Printf ("DynamicLoaderPOSIXDYLD::%s - got executable by pid %" PRIu64 ": %s", __FUNCTION__, m_process->GetID (), process_info.GetExecutableFile ().GetPath ().c_str ()); ModuleSpec module_spec (process_info.GetExecutableFile (), process_info.GetArchitecture ()); if (module_sp && module_sp->MatchesModuleSpec (module_spec)) return; const auto executable_search_paths (Target::GetDefaultExecutableSearchPaths()); auto error = platform_sp->ResolveExecutable ( module_spec, module_sp, !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr); if (error.Fail ()) { StreamString stream; module_spec.Dump (stream); if (log) log->Printf ("DynamicLoaderPOSIXDYLD::%s - failed to resolve executable with module spec \"%s\": %s", __FUNCTION__, stream.GetString ().c_str (), error.AsCString ()); return; } target.SetExecutableModule (module_sp, false); }
lldb_private::Error PlatformMacOSX::GetSharedModule (const lldb_private::ModuleSpec &module_spec, Process* process, lldb::ModuleSP &module_sp, const lldb_private::FileSpecList *module_search_paths_ptr, lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr) { Error error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr); if (module_sp) { if (module_spec.GetArchitecture().GetCore() == ArchSpec::eCore_x86_64_x86_64h) { ObjectFile *objfile = module_sp->GetObjectFile(); if (objfile == NULL) { // We didn't find an x86_64h slice, fall back to a x86_64 slice ModuleSpec module_spec_x86_64 (module_spec); module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx"); lldb::ModuleSP x86_64_module_sp; lldb::ModuleSP old_x86_64_module_sp; bool did_create = false; Error x86_64_error = GetSharedModuleWithLocalCache(module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, &old_x86_64_module_sp, &did_create); if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) { module_sp = x86_64_module_sp; if (old_module_sp_ptr) *old_module_sp_ptr = old_x86_64_module_sp; if (did_create_ptr) *did_create_ptr = did_create; return x86_64_error; } } } } return error; }
static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module, StreamWriter &&writer) { const ArchSpec &architecture = module->GetArchitecture(); ByteOrder byte_order = architecture.GetByteOrder(); uint32_t address_size = architecture.GetAddressByteSize(); uint32_t byte_size = architecture.GetDataByteSize(); if (byte_order == eByteOrderInvalid || address_size == 0) return DWARFExpression(nullptr); RegisterKind register_kind = eRegisterKindDWARF; StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); if (!writer(stream, register_kind)) return DWARFExpression(nullptr); DataBufferSP buffer = std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize()); DataExtractor extractor(buffer, byte_order, address_size, byte_size); DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize()); result.SetRegisterKind(register_kind); return result; }
ObjectFileSP ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, lldb::offset_t file_offset, lldb::offset_t file_size, DataBufferSP &data_sp, lldb::offset_t &data_offset) { ObjectFileSP object_file_sp; if (module_sp) { Timer scoped_timer (__PRETTY_FUNCTION__, "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")", module_sp->GetFileSpec().GetPath().c_str(), file, (uint64_t) file_offset, (uint64_t) file_size); if (file) { FileSpec archive_file; ObjectContainerCreateInstance create_object_container_callback; const bool file_exists = file->Exists(); if (!data_sp) { // We have an object name which most likely means we have // a .o file in a static archive (.a file). Try and see if // we have a cached archive first without reading any data // first if (file_exists && module_sp->GetObjectName()) { for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) { std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); if (object_container_ap.get()) object_file_sp = object_container_ap->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; } } // Ok, we didn't find any containers that have a named object, now // lets read the first 512 bytes from the file so the object file // and object container plug-ins can use these bytes to see if they // can parse this file. if (file_size > 0) { data_sp = file->ReadFileContents(file_offset, std::min<size_t>(512, file_size)); data_offset = 0; } } if (!data_sp || data_sp->GetByteSize() == 0) { // Check for archive file with format "/path/to/archive.a(object.o)" char path_with_object[PATH_MAX*2]; module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object)); ConstString archive_object; const bool must_exist = true; if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object, must_exist)) { file_size = archive_file.GetByteSize(); if (file_size > 0) { file = &archive_file; module_sp->SetFileSpecAndObjectName (archive_file, archive_object); // Check if this is a object container by iterating through all object // container plugin instances and then trying to get an object file // from the container plugins since we had a name. Also, don't read // ANY data in case there is data cached in the container plug-ins // (like BSD archives caching the contained objects within an file). for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) { std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); if (object_container_ap.get()) object_file_sp = object_container_ap->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; } // We failed to find any cached object files in the container // plug-ins, so lets read the first 512 bytes and try again below... data_sp = archive_file.ReadFileContents(file_offset, 512); } } } if (data_sp && data_sp->GetByteSize() > 0) { // Check if this is a normal object file by iterating through // all object file plugin instances. ObjectFileCreateInstance create_object_file_callback; for (uint32_t idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx) { object_file_sp.reset (create_object_file_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); if (object_file_sp.get()) return object_file_sp; } // Check if this is a object container by iterating through // all object container plugin instances and then trying to get // an object file from the container. for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) { std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size)); if (object_container_ap.get()) object_file_sp = object_container_ap->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; } } } } // We didn't find it, so clear our shared pointer in case it // contains anything and return an empty shared pointer object_file_sp.reset(); return object_file_sp; }
Error ModuleCache::GetAndPut(const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, const ModuleDownloader &module_downloader, const SymfileDownloader &symfile_downloader, lldb::ModuleSP &cached_module_sp, bool *did_create_ptr) { const auto module_spec_dir = GetModuleDirectory(root_dir_spec, module_spec.GetUUID()); auto error = MakeDirectory(module_spec_dir); if (error.Fail()) return error; ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error); if (error.Fail()) return Error("Failed to lock module %s: %s", module_spec.GetUUID().GetAsString().c_str(), error.AsCString()); const auto escaped_hostname(GetEscapedHostname(hostname)); // Check local cache for a module. error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr); if (error.Success()) return error; const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName); error = module_downloader(module_spec, tmp_download_file_spec); llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath().c_str()); if (error.Fail()) return Error("Failed to download module: %s", error.AsCString()); // Put downloaded file into local module cache. error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, tmp_download_file_spec, module_spec.GetFileSpec()); if (error.Fail()) return Error("Failed to put module into cache: %s", error.AsCString()); tmp_file_remover.releaseFile(); error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr); if (error.Fail()) return error; // Fetching a symbol file for the module const auto tmp_download_sym_file_spec = JoinPath(module_spec_dir, kTempSymFileName); error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec); llvm::FileRemover tmp_symfile_remover( tmp_download_sym_file_spec.GetPath().c_str()); if (error.Fail()) // Failed to download a symfile but fetching the module was successful. The // module might // contain the necessary symbols and the debugging is also possible without // a symfile. return Error(); error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, tmp_download_sym_file_spec, GetSymbolFileSpec(module_spec.GetFileSpec())); if (error.Fail()) return Error("Failed to put symbol file into cache: %s", error.AsCString()); tmp_symfile_remover.releaseFile(); FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec()); cached_module_sp->SetSymbolFileFileSpec(symfile_spec); return Error(); }
Error PlatformKalimba::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; char exe_path[PATH_MAX]; FileSpec resolved_exe_file (exe_file); if (!resolved_exe_file.Exists()) { exe_file.GetPath(exe_path, sizeof(exe_path)); error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); } if (error.Success()) { ModuleSpec module_spec (resolved_exe_file, exe_arch); if (exe_arch.IsValid()) { error = ModuleList::GetSharedModule (module_spec, exe_module_sp, NULL, NULL, NULL); if (error.Fail()) { // If we failed, it may be because the vendor and os aren't known. If that is the // case, try setting them to the host architecture and give it another try. llvm::Triple &module_triple = module_spec.GetArchitecture().GetTriple(); bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); if (!is_vendor_specified || !is_os_specified) { const llvm::Triple &host_triple = Host::GetArchitecture (Host::eSystemDefaultArchitecture).GetTriple(); if (!is_vendor_specified) module_triple.setVendorName (host_triple.getVendorName()); if (!is_os_specified) module_triple.setOSName (host_triple.getOSName()); error = ModuleList::GetSharedModule (module_spec, exe_module_sp, NULL, NULL, NULL); } } // TODO find out why exe_module_sp might be NULL if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", exe_file.GetPath().c_str(), exe_arch.GetArchitectureName()); } } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way StreamString arch_names; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule (module_spec, exe_module_sp, NULL, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", exe_file.GetPath().c_str(), GetPluginName().GetCString(), arch_names.GetString().c_str()); } } } return error; }
Error PlatformLinux::ResolveExecutable (const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; // Nothing special to do here, just use the actual file and architecture char exe_path[PATH_MAX]; ModuleSpec resolved_module_spec (ms); if (IsHost()) { // If we have "ls" as the exe_file, resolve the executable location based on // the current path variables if (!resolved_module_spec.GetFileSpec().Exists()) { resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); resolved_module_spec.GetFileSpec().SetFile(exe_path, true); } if (!resolved_module_spec.GetFileSpec().Exists()) resolved_module_spec.GetFileSpec().ResolveExecutableLocation (); if (resolved_module_spec.GetFileSpec().Exists()) error.Clear(); else { error.SetErrorStringWithFormat("unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } else { if (m_remote_platform_sp) { error = m_remote_platform_sp->ResolveExecutable (ms, exe_module_sp, NULL); } else { // We may connect to a process and use the provided executable (Don't use local $PATH). if (resolved_module_spec.GetFileSpec().Exists()) error.Clear(); else error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); } } if (error.Success()) { if (resolved_module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); if (error.Fail()) { // If we failed, it may be because the vendor and os aren't known. If that is the // case, try setting them to the host architecture and give it another try. llvm::Triple &module_triple = resolved_module_spec.GetArchitecture().GetTriple(); bool is_vendor_specified = (module_triple.getVendor() != llvm::Triple::UnknownVendor); bool is_os_specified = (module_triple.getOS() != llvm::Triple::UnknownOS); if (!is_vendor_specified || !is_os_specified) { const llvm::Triple &host_triple = HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); if (!is_vendor_specified) module_triple.setVendorName (host_triple.getVendorName()); if (!is_os_specified) module_triple.setOSName (host_triple.getOSName()); error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); } } // TODO find out why exe_module_sp might be NULL if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), resolved_module_spec.GetArchitecture().GetArchitectureName()); } } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way StreamString arch_names; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { if (resolved_module_spec.GetFileSpec().Readable()) { error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), GetPluginName().GetCString(), arch_names.GetString().c_str()); } else { error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } } } return error; }
Error PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, lldb::ModuleSP &exe_module_sp) { Error error; // Nothing special to do here, just use the actual file and architecture FileSpec resolved_exe_file (exe_file); // If we have "ls" as the exe_file, resolve the executable loation based on // the current path variables // TODO: resolve bare executables in the Platform SDK // if (!resolved_exe_file.Exists()) // resolved_exe_file.ResolveExecutableLocation (); // Resolve any executable within a bundle on MacOSX // TODO: verify that this handles shallow bundles, if not then implement one ourselves Host::ResolveExecutableInBundle (resolved_exe_file); if (resolved_exe_file.Exists()) { if (exe_arch.IsValid()) { error = ModuleList::GetSharedModule (resolved_exe_file, exe_arch, NULL, NULL, 0, exe_module_sp, NULL, NULL); if (exe_module_sp->GetObjectFile()) return error; exe_module_sp.reset(); } // No valid architecture was specified or the exact ARM slice wasn't // found so ask the platform for the architectures that we should be // using (in the correct order) and see if we can find a match that way StreamString arch_names; ArchSpec platform_arch; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, platform_arch); ++idx) { error = ModuleList::GetSharedModule (resolved_exe_file, platform_arch, NULL, NULL, 0, exe_module_sp, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (platform_arch.GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString(""), GetShortPluginName(), arch_names.GetString().c_str()); } } else { error.SetErrorStringWithFormat ("'%s%s%s' does not exist", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString("")); } return error; }
Error PlatformLinux::ResolveExecutable (const FileSpec &exe_file, const ArchSpec &exe_arch, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; // Nothing special to do here, just use the actual file and architecture char exe_path[PATH_MAX]; FileSpec resolved_exe_file (exe_file); if (IsHost()) { // If we have "ls" as the exe_file, resolve the executable location based on // the current path variables if (!resolved_exe_file.Exists()) { exe_file.GetPath(exe_path, sizeof(exe_path)); resolved_exe_file.SetFile(exe_path, true); } if (!resolved_exe_file.Exists()) resolved_exe_file.ResolveExecutableLocation (); if (resolved_exe_file.Exists()) error.Clear(); else { exe_file.GetPath(exe_path, sizeof(exe_path)); error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); } } else { if (m_remote_platform_sp) { error = m_remote_platform_sp->ResolveExecutable (exe_file, exe_arch, exe_module_sp, NULL); } else { // We may connect to a process and use the provided executable (Don't use local $PATH). if (resolved_exe_file.Exists()) error.Clear(); else error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); } } if (error.Success()) { ModuleSpec module_spec (resolved_exe_file, exe_arch); if (exe_arch.IsValid()) { error = ModuleList::GetSharedModule (module_spec, exe_module_sp, NULL, NULL, NULL); // TODO find out why exe_module_sp might be NULL if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain the architecture %s", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString(""), exe_arch.GetArchitectureName()); } } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way StreamString arch_names; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule (module_spec, exe_module_sp, NULL, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (module_spec.GetArchitecture().GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { error.SetErrorStringWithFormat ("'%s%s%s' doesn't contain any '%s' platform architectures: %s", exe_file.GetDirectory().AsCString(""), exe_file.GetDirectory() ? "/" : "", exe_file.GetFilename().AsCString(""), GetShortPluginName(), arch_names.GetString().c_str()); } } } return error; }
ObjectFileSP ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp) { ObjectFileSP object_file_sp; if (module_sp) { Timer scoped_timer (__PRETTY_FUNCTION__, "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%8.8llx, file_size = 0x%8.8llx)", module_sp->GetFileSpec().GetDirectory().AsCString(), module_sp->GetFileSpec().GetFilename().AsCString(), file, (uint64_t) file_offset, (uint64_t) file_size); if (file) { // Memory map the entire file contents if (!file_data_sp && file_size > 0) { assert (file_offset == 0); file_data_sp = file->MemoryMapFileContents(file_offset, file_size); } if (!file_data_sp || file_data_sp->GetByteSize() == 0) { // Check for archive file with format "/path/to/archive.a(object.o)" char path_with_object[PATH_MAX*2]; module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object)); FileSpec archive_file; ConstString archive_object; if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object)) { file_size = archive_file.GetByteSize(); if (file_size > 0) { module_sp->SetFileSpecAndObjectName (archive_file, archive_object); file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size); } } } if (file_data_sp && file_data_sp->GetByteSize() > 0) { uint32_t idx; // Check if this is a normal object file by iterating through // all object file plugin instances. ObjectFileCreateInstance create_object_file_callback; for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx) { object_file_sp.reset (create_object_file_callback(module_sp, file_data_sp, file, file_offset, file_size)); if (object_file_sp.get()) return object_file_sp; } // Check if this is a object container by iterating through // all object container plugin instances and then trying to get // an object file from the container. ObjectContainerCreateInstance create_object_container_callback; for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx) { std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, file_data_sp, file, file_offset, file_size)); if (object_container_ap.get()) object_file_sp = object_container_ap->GetObjectFile(file); if (object_file_sp.get()) return object_file_sp; } } } } // We didn't find it, so clear our shared pointer in case it // contains anything and return an empty shared pointer object_file_sp.reset(); return object_file_sp; }
Error PlatformFreeBSD::ResolveExecutable( const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; // Nothing special to do here, just use the actual file and architecture char exe_path[PATH_MAX]; ModuleSpec resolved_module_spec(module_spec); if (IsHost()) { // If we have "ls" as the module_spec's file, resolve the executable // location based on // the current path variables if (!resolved_module_spec.GetFileSpec().Exists()) { module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); resolved_module_spec.GetFileSpec().SetFile(exe_path, true); } if (!resolved_module_spec.GetFileSpec().Exists()) resolved_module_spec.GetFileSpec().ResolveExecutableLocation(); if (resolved_module_spec.GetFileSpec().Exists()) error.Clear(); else { error.SetErrorStringWithFormat( "unable to find executable for '%s'", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } else { if (m_remote_platform_sp) { error = GetCachedExecutable(resolved_module_spec, exe_module_sp, module_search_paths_ptr, *m_remote_platform_sp); } else { // We may connect to a process and use the provided executable (Don't use // local $PATH). // Resolve any executable within a bundle on MacOSX Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); if (resolved_module_spec.GetFileSpec().Exists()) { error.Clear(); } else { error.SetErrorStringWithFormat( "the platform is not currently connected, and '%s' doesn't exist " "in the system root.", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } } if (error.Success()) { if (resolved_module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, module_search_paths_ptr, NULL, NULL); if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL) { exe_module_sp.reset(); error.SetErrorStringWithFormat( "'%s' doesn't contain the architecture %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), resolved_module_spec.GetArchitecture().GetArchitectureName()); } } else { // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way StreamString arch_names; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( idx, resolved_module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, module_search_paths_ptr, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString(", "); arch_names.PutCString( resolved_module_spec.GetArchitecture().GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { if (resolved_module_spec.GetFileSpec().Readable()) { error.SetErrorStringWithFormat( "'%s' doesn't contain any '%s' platform architectures: %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), GetPluginName().GetCString(), arch_names.GetData()); } else { error.SetErrorStringWithFormat( "'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } } } return error; }
Error PlatformAndroid::DownloadSymbolFile (const lldb::ModuleSP& module_sp, const FileSpec& dst_file_spec) { // For oat file we can try to fetch additional debug info from the device if (module_sp->GetFileSpec().GetFileNameExtension() != ConstString("oat")) return Error("Symbol file downloading only supported for oat files"); // If we have no information about the platform file we can't execute oatdump if (!module_sp->GetPlatformFileSpec()) return Error("No platform file specified"); // Symbolizer isn't available before SDK version 23 if (GetSdkVersion() < 23) return Error("Symbol file generation only supported on SDK 23+"); // If we already have symtab then we don't have to try and generate one if (module_sp->GetSectionList()->FindSectionByName(ConstString(".symtab")) != nullptr) return Error("Symtab already available in the module"); int status = 0; std::string tmpdir; StreamString command; command.Printf("mktemp --directory --tmpdir %s", GetWorkingDirectory().GetCString()); Error error = RunShellCommand(command.GetData(), GetWorkingDirectory(), &status, nullptr, &tmpdir, 5 /* timeout (s) */); if (error.Fail() || status != 0 || tmpdir.empty()) return Error("Failed to generate temporary directory on the device (%s)", error.AsCString()); tmpdir.erase(tmpdir.size() - 1); // Remove trailing new line // Create file remover for the temporary directory created on the device std::unique_ptr<std::string, std::function<void(std::string*)>> tmpdir_remover( &tmpdir, [this](std::string* s) { StreamString command; command.Printf("rm -rf %s", s->c_str()); Error error = this->RunShellCommand(command.GetData(), GetWorkingDirectory(), nullptr, nullptr, nullptr, 5 /* timeout (s) */); Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_PLATFORM)); if (error.Fail()) log->Printf("Failed to remove temp directory: %s", error.AsCString()); } ); FileSpec symfile_platform_filespec(tmpdir.c_str(), false); symfile_platform_filespec.AppendPathComponent("symbolized.oat"); // Execute oatdump on the remote device to generate a file with symtab command.Clear(); command.Printf("oatdump --symbolize=%s --output=%s", module_sp->GetPlatformFileSpec().GetCString(false), symfile_platform_filespec.GetCString(false)); error = RunShellCommand(command.GetData(), GetWorkingDirectory(), &status, nullptr, nullptr, 60 /* timeout (s) */); if (error.Fail() || status != 0) return Error("Oatdump failed: %s", error.AsCString()); // Download the symbolfile from the remote device return GetFile(symfile_platform_filespec, dst_file_spec); }
Error PlatformRemoteiOS::ResolveExecutable (const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Error error; // Nothing special to do here, just use the actual file and architecture ModuleSpec resolved_module_spec(ms); // Resolve any executable within a bundle on MacOSX // TODO: verify that this handles shallow bundles, if not then implement one ourselves Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); if (resolved_module_spec.GetFileSpec().Exists()) { if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); if (exe_module_sp && exe_module_sp->GetObjectFile()) return error; exe_module_sp.reset(); } // No valid architecture was specified or the exact ARM slice wasn't // found so ask the platform for the architectures that we should be // using (in the correct order) and see if we can find a match that way StreamString arch_names; for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, NULL, NULL, NULL); // Did we find an executable using one of the if (error.Success()) { if (exe_module_sp && exe_module_sp->GetObjectFile()) break; else error.SetErrorToGenericError(); } if (idx > 0) arch_names.PutCString (", "); arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); } if (error.Fail() || !exe_module_sp) { if (resolved_module_spec.GetFileSpec().Readable()) { error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), GetPluginName().GetCString(), arch_names.GetString().c_str()); } else { error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); } } } else { error.SetErrorStringWithFormat ("'%s' does not exist", resolved_module_spec.GetFileSpec().GetPath().c_str()); } return error; }
Error ModuleCache::GetAndPut (const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, const ModuleDownloader &module_downloader, const SymfileDownloader &symfile_downloader, lldb::ModuleSP &cached_module_sp, bool *did_create_ptr) { const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ()); auto error = MakeDirectory (module_spec_dir); if (error.Fail ()) return error; // Open lock file. const auto lock_file_spec = JoinPath (module_spec_dir, kLockFileName); File lock_file (lock_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); if (!lock_file) { error.SetErrorToErrno (); return Error("Failed to open lock file %s: %s", lock_file_spec.GetPath ().c_str (), error.AsCString ()); } LockFile lock (lock_file.GetDescriptor ()); error = lock.WriteLock (0, 1); if (error.Fail ()) return Error("Failed to lock file %s:%s", lock_file_spec.GetPath ().c_str (), error.AsCString ()); // Check local cache for a module. error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); if (error.Success ()) return error; const auto tmp_download_file_spec = JoinPath (module_spec_dir, kTempFileName); error = module_downloader (module_spec, tmp_download_file_spec); llvm::FileRemover tmp_file_remover (tmp_download_file_spec.GetPath ().c_str ()); if (error.Fail ()) return Error("Failed to download module: %s", error.AsCString ()); // Put downloaded file into local module cache. error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ()); if (error.Fail ()) return Error ("Failed to put module into cache: %s", error.AsCString ()); tmp_file_remover.releaseFile (); error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); if (error.Fail ()) return error; // Fetching a symbol file for the module const auto tmp_download_sym_file_spec = JoinPath (module_spec_dir, kTempSymFileName); error = symfile_downloader (cached_module_sp, tmp_download_sym_file_spec); llvm::FileRemover tmp_symfile_remover (tmp_download_sym_file_spec.GetPath ().c_str ()); if (error.Fail ()) // Failed to download a symfile but fetching the module was successful. The module might // contain the neccessary symbols and the debugging is also possible without a symfile. return Error (); FileSpec symfile_spec = GetSymbolFileSpec (cached_module_sp->GetFileSpec ()); error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, symfile_spec); if (error.Fail ()) return Error ("Failed to put symbol file into cache: %s", error.AsCString ()); tmp_symfile_remover.releaseFile(); cached_module_sp->SetSymbolFileFileSpec (symfile_spec); return Error (); }