예제 #1
0
ModuleSP DynamicLoader::GetTargetExecutable() {
  Target &target = m_process->GetTarget();
  ModuleSP executable = target.GetExecutableModule();

  if (executable) {
    if (FileSystem::Instance().Exists(executable->GetFileSpec())) {
      ModuleSpec module_spec(executable->GetFileSpec(),
                             executable->GetArchitecture());
      auto module_sp = std::make_shared<Module>(module_spec);

      // Check if the executable has changed and set it to the target
      // executable if they differ.
      if (module_sp && module_sp->GetUUID().IsValid() &&
          executable->GetUUID().IsValid()) {
        if (module_sp->GetUUID() != executable->GetUUID())
          executable.reset();
      } else if (executable->FileHasChanged()) {
        executable.reset();
      }

      if (!executable) {
        executable = target.GetOrCreateModule(module_spec, true /* notify */);
        if (executable.get() != target.GetExecutableModulePointer()) {
          // Don't load dependent images since we are in dyld where we will
          // know and find out about all images that are loaded
          target.SetExecutableModule(executable, eLoadDependentsNo);
        }
      }
    }
  }
  return executable;
}
예제 #2
0
/// Checks to see if the target module has changed, updates the target
/// accordingly and returns the target executable module.
ModuleSP
DynamicLoaderHexagonDYLD::GetTargetExecutable()
{
    Target &target = m_process->GetTarget();
    ModuleSP executable = target.GetExecutableModule();

    // There is no executable
    if (! executable.get())
        return executable;

    // The target executable file does not exits
    if (! executable->GetFileSpec().Exists())
        return executable;
    
    // Prep module for loading
    ModuleSpec module_spec(executable->GetFileSpec(), executable->GetArchitecture());
    ModuleSP   module_sp  (new Module (module_spec));

    // Check if the executable has changed and set it to the target executable if they differ.
    if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
    {
        // if the executable has changed ??
        if (module_sp->GetUUID() != executable->GetUUID())
            executable.reset();
    }
    else if (executable->FileHasChanged())
        executable.reset();

    if ( executable.get( ) )
        return executable;

    // TODO: What case is this code used?
    executable = target.GetSharedModule(module_spec);
    if (executable.get() != target.GetExecutableModulePointer())
    {
        // Don't load dependent images since we are in dyld where we will know
        // and find out about all images that are loaded
        const bool get_dependent_images = false;
        target.SetExecutableModule(executable, get_dependent_images);
    }
    
    return executable;
}
예제 #3
0
    //--------------------------------------------------------------
    /// Unary predicate function object callback.
    //--------------------------------------------------------------
    bool
    operator () (const ModuleSP& module_sp) const
    {
        if (m_file_spec_ptr)
        {
            if (m_file_spec_is_platform)
            {
                if (!FileSpec::Equal (*m_file_spec_ptr, 
                                      module_sp->GetPlatformFileSpec(), 
                                      m_file_spec_compare_basename_only))
                    return false;
        
            }
            else
            {
                if (!FileSpec::Equal (*m_file_spec_ptr, 
                                      module_sp->GetFileSpec(), 
                                      m_file_spec_compare_basename_only))
                    return false;
            }
        }

        if (m_arch_ptr && m_arch_ptr->IsValid())
        {
            if (module_sp->GetArchitecture() != *m_arch_ptr)
                return false;
        }

        if (m_uuid_ptr && m_uuid_ptr->IsValid())
        {
            if (module_sp->GetUUID() != *m_uuid_ptr)
                return false;
        }

        if (m_object_name)
        {
            if (module_sp->GetObjectName() != *m_object_name)
                return false;
        }
        return true;
    }
예제 #4
0
Error
PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
                                    ModuleSP &module_sp,
                                    const FileSpecList *module_search_paths_ptr,
                                    ModuleSP *old_module_sp_ptr,
                                    bool *did_create_ptr)
{
    // For iOS, the SDK files are all cached locally on the host
    // system. So first we ask for the file in the cached SDK,
    // then we attempt to get a shared module for the right architecture
    // with the right UUID.
    const FileSpec &platform_file = module_spec.GetFileSpec();

    FileSpec local_file;
    const UUID *module_uuid_ptr = module_spec.GetUUIDPtr();
    Error error (GetSymbolFile (platform_file, module_uuid_ptr, local_file));
    if (error.Success())
    {
        error = ResolveExecutable (local_file, module_spec.GetArchitecture(), module_sp, NULL);
        if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
        {
            //printf ("found in user specified SDK\n");
            error.Clear();
            return error;
        }

        char platform_file_path[PATH_MAX];
        if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path)))
        {
            FileSpec local_file;
            const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
            // Try the last SDK index if it is set as most files from an SDK
            // will tend to be valid in that same SDK.
            if (m_last_module_sdk_idx < num_sdk_infos)
            {
                if (GetFileInSDK (platform_file_path, m_last_module_sdk_idx, local_file))
                {
                    //printf ("sdk[%u] last: '%s'\n", m_last_module_sdk_idx, local_file.GetPath().c_str());
                    module_sp.reset();
                    error = ResolveExecutable (local_file,
                                               module_spec.GetArchitecture(),
                                               module_sp,
                                               NULL);
                    if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
                    {
                        //printf ("sdk[%u] last found\n", m_last_module_sdk_idx);
                        error.Clear();
                        return error;
                    }
                }
            }
            
            // First try for an exact match of major, minor and update
            for (uint32_t sdk_idx=0; sdk_idx<num_sdk_infos; ++sdk_idx)
            {
                if (m_last_module_sdk_idx == sdk_idx)
                {
                    // Skip the last module SDK index if we already searched
                    // it above
                    continue;
                }
                if (GetFileInSDK (platform_file_path, sdk_idx, local_file))
                {
                    //printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
                    
                    error = ResolveExecutable (local_file,
                                               module_spec.GetArchitecture(),
                                               module_sp,
                                               NULL);
                    if (module_sp && ((module_uuid_ptr == NULL) || (module_sp->GetUUID() == *module_uuid_ptr)))
                    {
                        // Remember the index of the last SDK that we found a file
                        // in in case the wrong SDK was selected.
                        m_last_module_sdk_idx = sdk_idx;
                        //printf ("sdk[%u]: found (setting last to %u)\n", sdk_idx, m_last_module_sdk_idx);
                        error.Clear();
                        return error;
                    }
                }
            }
        }
        // Not the module we are looking for... Nothing to see here...
        module_sp.reset();
    }
    else
    {
        // This may not be an SDK-related module.  Try whether we can bring in the thing to our local cache.
        error = GetSharedModuleWithLocalCache(module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr);
        if (error.Success())
            return error;
        else
            error.Clear(); // Clear the error and fall-through.
    }

    const bool always_create = false;
    error = ModuleList::GetSharedModule (module_spec, 
                                         module_sp,
                                         module_search_paths_ptr,
                                         old_module_sp_ptr,
                                         did_create_ptr,
                                         always_create);

    if (module_sp)
        module_sp->SetPlatformFileSpec(platform_file);

    return error;
}
예제 #5
0
Error
ModuleList::GetSharedModule(const ModuleSpec &module_spec,
                            ModuleSP &module_sp,
                            const FileSpecList *module_search_paths_ptr,
                            ModuleSP *old_module_sp_ptr,
                            bool *did_create_ptr,
                            bool always_create)
{
    ModuleList &shared_module_list = GetSharedModuleList ();
    Mutex::Locker locker(shared_module_list.m_modules_mutex);
    char path[PATH_MAX];

    Error error;

    module_sp.reset();

    if (did_create_ptr)
        *did_create_ptr = false;
    if (old_module_sp_ptr)
        old_module_sp_ptr->reset();

    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
    const FileSpec &module_file_spec = module_spec.GetFileSpec();
    const ArchSpec &arch = module_spec.GetArchitecture();

    // Make sure no one else can try and get or create a module while this
    // function is actively working on it by doing an extra lock on the
    // global mutex list.
    if (!always_create)
    {
        ModuleList matching_module_list;
        const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
        if (num_matching_modules > 0)
        {
            for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
            {
                module_sp = matching_module_list.GetModuleAtIndex(module_idx);

                // Make sure the file for the module hasn't been modified
                if (module_sp->FileHasChanged())
                {
                    if (old_module_sp_ptr && !*old_module_sp_ptr)
                        *old_module_sp_ptr = module_sp;

                    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
                    if (log != nullptr)
                        log->Printf("module changed: %p, removing from global module list",
                                    static_cast<void*>(module_sp.get()));

                    shared_module_list.Remove (module_sp);
                    module_sp.reset();
                }
                else
                {
                    // The module matches and the module was not modified from
                    // when it was last loaded.
                    return error;
                }
            }
        }
    }

    if (module_sp)
        return error;

    module_sp.reset (new Module (module_spec));
    // Make sure there are a module and an object file since we can specify
    // a valid file path with an architecture that might not be in that file.
    // By getting the object file we can guarantee that the architecture matches
    if (module_sp->GetObjectFile())
    {
        // If we get in here we got the correct arch, now we just need
        // to verify the UUID if one was given
        if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
        {
            module_sp.reset();
        }
        else
        {
            if (module_sp->GetObjectFile() && module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
            {
                module_sp.reset();
            }
            else
            {
                if (did_create_ptr)
                {
                    *did_create_ptr = true;
                }

                shared_module_list.ReplaceEquivalent(module_sp);
                return error;
            }
        }
    }
    else
    {
        module_sp.reset();
    }

    if (module_search_paths_ptr)
    {
        const auto num_directories = module_search_paths_ptr->GetSize();
        for (size_t idx = 0; idx < num_directories; ++idx)
        {
            auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
            if (!search_path_spec.ResolvePath())
                continue;
            if (!search_path_spec.Exists() || !search_path_spec.IsDirectory())
                continue;
            search_path_spec.AppendPathComponent(module_spec.GetFileSpec().GetFilename().AsCString());
            if (!search_path_spec.Exists())
                continue;

            auto resolved_module_spec(module_spec);
            resolved_module_spec.GetFileSpec() = search_path_spec;
            module_sp.reset (new Module (resolved_module_spec));
            if (module_sp->GetObjectFile())
            {
                // If we get in here we got the correct arch, now we just need
                // to verify the UUID if one was given
                if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
                {
                    module_sp.reset();
                }
                else
                {
                    if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
                    {
                        module_sp.reset();
                    }
                    else
                    {
                        if (did_create_ptr)
                            *did_create_ptr = true;
    
                        shared_module_list.ReplaceEquivalent(module_sp);
                        return Error();
                    }
                }
            }
            else
            {
                module_sp.reset();
            }
        }
    }

    // Either the file didn't exist where at the path, or no path was given, so
    // we now have to use more extreme measures to try and find the appropriate
    // module.

    // Fixup the incoming path in case the path points to a valid file, yet
    // the arch or UUID (if one was passed in) don't match.
    ModuleSpec located_binary_modulespec = Symbols::LocateExecutableObjectFile (module_spec);

    // Don't look for the file if it appears to be the same one we already
    // checked for above...
    if (located_binary_modulespec.GetFileSpec() != module_file_spec)
    {
        if (!located_binary_modulespec.GetFileSpec().Exists())
        {
            located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
            if (path[0] == '\0')
                module_file_spec.GetPath(path, sizeof(path));
            // How can this check ever be true? This branch it is false, and we haven't modified file_spec.
            if (located_binary_modulespec.GetFileSpec().Exists())
            {
                std::string uuid_str;
                if (uuid_ptr && uuid_ptr->IsValid())
                    uuid_str = uuid_ptr->GetAsString();

                if (arch.IsValid())
                {
                    if (!uuid_str.empty())
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str());
                    else
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
                }
            }
            else
            {
                error.SetErrorStringWithFormat("'%s' does not exist", path);
            }
            if (error.Fail())
                module_sp.reset();
            return error;
        }

        // Make sure no one else can try and get or create a module while this
        // function is actively working on it by doing an extra lock on the
        // global mutex list.
        ModuleSpec platform_module_spec(module_spec);
        platform_module_spec.GetFileSpec() = located_binary_modulespec.GetFileSpec();
        platform_module_spec.GetPlatformFileSpec() = located_binary_modulespec.GetFileSpec();
        platform_module_spec.GetSymbolFileSpec() = located_binary_modulespec.GetSymbolFileSpec();
        ModuleList matching_module_list;
        if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0)
        {
            module_sp = matching_module_list.GetModuleAtIndex(0);

            // If we didn't have a UUID in mind when looking for the object file,
            // then we should make sure the modification time hasn't changed!
            if (platform_module_spec.GetUUIDPtr() == nullptr)
            {
                TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
                if (file_spec_mod_time.IsValid())
                {
                    if (file_spec_mod_time != module_sp->GetModificationTime())
                    {
                        if (old_module_sp_ptr)
                            *old_module_sp_ptr = module_sp;
                        shared_module_list.Remove (module_sp);
                        module_sp.reset();
                    }
                }
            }
        }

        if (!module_sp)
        {
            module_sp.reset (new Module (platform_module_spec));
            // Make sure there are a module and an object file since we can specify
            // a valid file path with an architecture that might not be in that file.
            // By getting the object file we can guarantee that the architecture matches
            if (module_sp && module_sp->GetObjectFile())
            {
                if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary)
                {
                    module_sp.reset();
                }
                else
                {
                    if (did_create_ptr)
                        *did_create_ptr = true;

                    shared_module_list.ReplaceEquivalent(module_sp);
                }
            }
            else
            {
                located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));

                if (located_binary_modulespec.GetFileSpec())
                {
                    if (arch.IsValid())
                        error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
                    else
                        error.SetErrorStringWithFormat("unable to open '%s'", path);
                }
                else
                {
                    std::string uuid_str;
                    if (uuid_ptr && uuid_ptr->IsValid())
                        uuid_str = uuid_ptr->GetAsString();

                    if (!uuid_str.empty())
                        error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str());
                    else
                        error.SetErrorStringWithFormat("cannot locate a module");
                }
            }
        }
    }

    return error;
}
예제 #6
0
Error
ModuleList::GetSharedModule
(
    const FileSpec& in_file_spec,
    const ArchSpec& arch,
    const lldb_private::UUID *uuid_ptr,
    const ConstString *object_name_ptr,
    off_t object_offset,
    ModuleSP &module_sp,
    ModuleSP *old_module_sp_ptr,
    bool *did_create_ptr,
    bool always_create
)
{
    ModuleList &shared_module_list = GetSharedModuleList ();
    Mutex::Locker locker(shared_module_list.m_modules_mutex);
    char path[PATH_MAX];
    char uuid_cstr[64];

    Error error;

    module_sp.reset();

    if (did_create_ptr)
        *did_create_ptr = false;
    if (old_module_sp_ptr)
        old_module_sp_ptr->reset();


    // First just try and get the file where it purports to be (path in
    // in_file_spec), then check and uuid.

    if (in_file_spec)
    {
        // Make sure no one else can try and get or create a module while this
        // function is actively working on it by doing an extra lock on the
        // global mutex list.
        if (always_create == false)
        {
            ModuleList matching_module_list;
            const size_t num_matching_modules = shared_module_list.FindModules (&in_file_spec, &arch, NULL, object_name_ptr, matching_module_list);
            if (num_matching_modules > 0)
            {
                for (uint32_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
                {
                    module_sp = matching_module_list.GetModuleAtIndex(module_idx);
                    if (uuid_ptr && uuid_ptr->IsValid())
                    {
                        // We found the module we were looking for.
                        if (module_sp->GetUUID() == *uuid_ptr)
                            return error;
                    }
                    else
                    {
                        // If we didn't have a UUID in mind when looking for the object file,
                        // then we should make sure the modification time hasn't changed!
                        TimeValue file_spec_mod_time(in_file_spec.GetModificationTime());
                        if (file_spec_mod_time.IsValid())
                        {
                            if (file_spec_mod_time == module_sp->GetModificationTime())
                                return error;
                        }
                    }
                    if (old_module_sp_ptr && !old_module_sp_ptr->get())
                        *old_module_sp_ptr = module_sp;
                    shared_module_list.Remove (module_sp);
                    module_sp.reset();
                }
            }
        }

        if (module_sp)
            return error;
        else
        {
#if defined ENABLE_MODULE_SP_LOGGING
            ModuleSP logging_module_sp (new Module (in_file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, (void *)ConstString("a.out").GetCString());
            module_sp = logging_module_sp;
#else
            module_sp.reset (new Module (in_file_spec, arch, object_name_ptr, object_offset));
#endif
            // Make sure there are a module and an object file since we can specify
            // a valid file path with an architecture that might not be in that file.
            // By getting the object file we can guarantee that the architecture matches
            if (module_sp && module_sp->GetObjectFile())
            {
                // If we get in here we got the correct arch, now we just need
                // to verify the UUID if one was given
                if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
                    module_sp.reset();
                else
                {
                    if (did_create_ptr)
                        *did_create_ptr = true;
                    
                    shared_module_list.Append(module_sp);
                    return error;
                }
            }
        }
    }

    // Either the file didn't exist where at the path, or no path was given, so
    // we now have to use more extreme measures to try and find the appropriate
    // module.

    // Fixup the incoming path in case the path points to a valid file, yet
    // the arch or UUID (if one was passed in) don't match.
    FileSpec file_spec = Symbols::LocateExecutableObjectFile (in_file_spec ? &in_file_spec : NULL, 
                                                              arch.IsValid() ? &arch : NULL, 
                                                              uuid_ptr);

    // Don't look for the file if it appears to be the same one we already
    // checked for above...
    if (file_spec != in_file_spec)
    {
        if (!file_spec.Exists())
        {
            file_spec.GetPath(path, sizeof(path));
            if (file_spec.Exists())
            {
                if (uuid_ptr && uuid_ptr->IsValid())
                    uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr));
                else
                    uuid_cstr[0] = '\0';


                if (arch.IsValid())
                {
                    if (uuid_cstr[0])
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_cstr);
                    else
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
                }
            }
            else
            {
                error.SetErrorStringWithFormat("'%s' does not exist", path);
            }
            return error;
        }


        // Make sure no one else can try and get or create a module while this
        // function is actively working on it by doing an extra lock on the
        // global mutex list.
        ModuleList matching_module_list;
        if (shared_module_list.FindModules (&file_spec, &arch, uuid_ptr, object_name_ptr, matching_module_list) > 0)
        {
            module_sp = matching_module_list.GetModuleAtIndex(0);

            // If we didn't have a UUID in mind when looking for the object file,
            // then we should make sure the modification time hasn't changed!
            if (uuid_ptr == NULL)
            {
                TimeValue file_spec_mod_time(file_spec.GetModificationTime());
                if (file_spec_mod_time.IsValid())
                {
                    if (file_spec_mod_time != module_sp->GetModificationTime())
                    {
                        if (old_module_sp_ptr)
                            *old_module_sp_ptr = module_sp;
                        shared_module_list.Remove (module_sp);
                        module_sp.reset();
                    }
                }
            }
        }

        if (module_sp.get() == NULL)
        {
#if defined ENABLE_MODULE_SP_LOGGING
            ModuleSP logging_module_sp (new Module (file_spec, arch, object_name_ptr, object_offset), ModuleSharedPtrLogger, 0);
            module_sp = logging_module_sp;
#else
            module_sp.reset (new Module (file_spec, arch, object_name_ptr, object_offset));
#endif
            // Make sure there are a module and an object file since we can specify
            // a valid file path with an architecture that might not be in that file.
            // By getting the object file we can guarantee that the architecture matches
            if (module_sp && module_sp->GetObjectFile())
            {
                if (did_create_ptr)
                    *did_create_ptr = true;

                shared_module_list.Append(module_sp);
            }
            else
            {
                file_spec.GetPath(path, sizeof(path));

                if (file_spec)
                {
                    if (arch.IsValid())
                        error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
                    else
                        error.SetErrorStringWithFormat("unable to open '%s'", path);
                }
                else
                {
                    if (uuid_ptr && uuid_ptr->IsValid())
                        uuid_ptr->GetAsCString(uuid_cstr, sizeof (uuid_cstr));
                    else
                        uuid_cstr[0] = '\0';

                    if (uuid_cstr[0])
                        error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_cstr);
                    else
                        error.SetErrorStringWithFormat("cannot locate a module");
                }
            }
        }
    }

    return error;
}