blob: de007d0bbef6d859aacf1ad3a25e4117d644b268 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CRAZY_LINKER_GLOBALS_H
#define CRAZY_LINKER_GLOBALS_H
#include <pthread.h>
#include "crazy_linker_library_list.h"
#include "crazy_linker_pointer_set.h"
#include "crazy_linker_rdebug.h"
#include "crazy_linker_search_path_list.h"
// All crazy linker globals are declared in this header.
namespace crazy {
class Globals {
public:
// Get the single Globals instance for this process.
static Globals* Get();
// Default constructor.
Globals();
// Destructor.
~Globals();
// Acquire and release the mutex that protects all other non-static members.
// ScopedLockedGlobals is recommended, to avoid using these directly.
void Lock();
void Unlock();
// The list of libraries known to the crazy linker.
LibraryList* libraries() { return &libraries_; }
// The RDebug instance for this process.
RDebug* rdebug() { return &rdebug_; }
// Set of valid handles returned by the dlopen() wrapper. This is
// required to deal with rare cases where the wrapper is passed
// a handle that was opened with the system linker by mistake.
PointerSet* valid_handles() { return &valid_handles_; }
// The current library search path list used by the dlopen() wrapper.
// Initialized from LD_LIBRARY_PATH when ::Get() creates the instance.
SearchPathList* search_path_list() { return &search_paths_; }
// Save JavaVM instance pointer and minimum JNI version required by this
// client. If |java_vm| is not nullptr, it will be used to call JNI_OnLoad()
// on every library loaded through the crazy linker, if available, and
// JNI_UnLoad() when unloading them, respectively.
void InitJavaVm(void* java_vm, int min_jni_version) {
java_vm_ = java_vm;
min_jni_version_ = min_jni_version;
}
// Return current JavaVM instance pointer.
void* java_vm() const { return java_vm_; }
// Return current minimum JNI version number.
int minimum_jni_version() const { return min_jni_version_; }
// Convenience function to get the global RDebug instance.
static RDebug* GetRDebug() { return Get()->rdebug(); }
private:
pthread_mutex_t lock_;
void* java_vm_ = nullptr;
int min_jni_version_ = 0;
LibraryList libraries_;
SearchPathList search_paths_;
RDebug rdebug_;
PointerSet valid_handles_;
};
// Convenience class to retrieve the Globals instance and lock it at the same
// time on construction, then release it on destruction. Also dereference can
// be used to access global methods and members.
class ScopedLockedGlobals {
public:
// Default constructor acquires the lock on the global instance.
ScopedLockedGlobals() : globals_(Globals::Get()) { globals_->Lock(); }
// Destructor releases the lock.
~ScopedLockedGlobals() { globals_->Unlock(); }
// Disallow copy operations.
ScopedLockedGlobals(const ScopedLockedGlobals&) = delete;
ScopedLockedGlobals& operator=(const ScopedLockedGlobals&) = delete;
// Dereference operator.
Globals* operator->() { return globals_; }
private:
Globals* globals_;
};
// Convenience class used to operate on a mutex used to synchronize access to
// the global _r_debug link map, at least from threads using the crazy linker.
class ScopedLinkMapLocker {
public:
ScopedLinkMapLocker() { pthread_mutex_lock(&s_lock_); }
~ScopedLinkMapLocker() { pthread_mutex_unlock(&s_lock_); }
private:
static pthread_mutex_t s_lock_;
};
} // namespace crazy
#endif // CRAZY_LINKER_GLOBALS_H