Skip to content

Commit

Permalink
Revert "Refactor DynamicLibrary so searching for a symbol will have a…
Browse files Browse the repository at this point in the history
… defined order"

The i686-mingw32-RA-on-linux bot is still having errors.

This reverts commit r301236.

llvm-svn: 301240
  • Loading branch information
Frederich Munch committed Apr 24, 2017
1 parent 0f62eea commit fd96d5e
Showing 11 changed files with 285 additions and 576 deletions.
7 changes: 2 additions & 5 deletions llvm/include/llvm/Support/DynamicLibrary.h
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ namespace sys {
void *getAddressOfSymbol(const char *symbolName);

/// This function permanently loads the dynamic library at the given path.
/// The library will only be unloaded when llvm_shutdown() is called.
/// The library will only be unloaded when the program terminates.
/// This returns a valid DynamicLibrary instance on success and an invalid
/// instance on failure (see isValid()). \p *errMsg will only be modified
/// if the library fails to load.
@@ -71,8 +71,7 @@ namespace sys {
/// Registers an externally loaded library. The library will be unloaded
/// when the program terminates.
///
/// It is safe to call this function multiple times for the same library,
/// though ownership is only taken if there was no error.
/// It is safe to call this function multiple times for the same library.
///
/// \returns An empty \p DynamicLibrary if the library was already loaded.
static DynamicLibrary addPermanentLibrary(void *handle,
@@ -107,8 +106,6 @@ namespace sys {
/// libraries.
/// @brief Add searchable symbol/value pair.
static void AddSymbol(StringRef symbolName, void *symbolValue);

class HandleSet;
};

} // End sys namespace
1 change: 1 addition & 0 deletions llvm/lib/Support/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -130,6 +130,7 @@ add_llvm_library(LLVMSupport
Process.cpp
Program.cpp
RWMutex.cpp
SearchForAddressOfSpecialSymbol.cpp
Signals.cpp
TargetRegistry.cpp
ThreadLocal.cpp
237 changes: 121 additions & 116 deletions llvm/lib/Support/DynamicLibrary.cpp
Original file line number Diff line number Diff line change
@@ -20,164 +20,169 @@
#include "llvm/Support/Mutex.h"
#include <cstdio>
#include <cstring>
#include <vector>

// Collection of symbol name/value pairs to be searched prior to any libraries.
static llvm::ManagedStatic<llvm::StringMap<void *> > ExplicitSymbols;
static llvm::ManagedStatic<llvm::sys::SmartMutex<true> > SymbolsMutex;

void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
void *symbolValue) {
SmartScopedLock<true> lock(*SymbolsMutex);
(*ExplicitSymbols)[symbolName] = symbolValue;
}

char llvm::sys::DynamicLibrary::Invalid = 0;

#ifdef LLVM_ON_WIN32

#include "Windows/DynamicLibrary.inc"

#else

#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
#include <dlfcn.h>
using namespace llvm;
using namespace llvm::sys;

// All methods for HandleSet should be used holding SymbolsMutex.
class DynamicLibrary::HandleSet {
typedef std::vector<void *> HandleList;
HandleList Handles;
void *Process;

public:
static void *DLOpen(const char *Filename, std::string *Err);
static void DLClose(void *Handle);
static void *DLSym(void *Handle, const char *Symbol);
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//=== independent code.
//===----------------------------------------------------------------------===//

HandleSet() : Process(nullptr) {}
~HandleSet();
static llvm::ManagedStatic<DenseSet<void *> > OpenedHandles;

HandleList::iterator Find(void *Handle) {
return std::find(Handles.begin(), Handles.end(), Handle);
}
DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
std::string *errMsg) {
SmartScopedLock<true> lock(*SymbolsMutex);

bool Contains(void *Handle) {
return Handle == Process || Find(Handle) != Handles.end();
void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
if (!handle) {
if (errMsg) *errMsg = dlerror();
return DynamicLibrary();
}

bool AddLibrary(void *Handle, bool IsProcess = false, bool CanClose = true) {
#ifdef LLVM_ON_WIN32
assert((Handle == this ? IsProcess : !IsProcess) && "Bad Handle.");
#ifdef __CYGWIN__
// Cygwin searches symbols only in the main
// with the handle of dlopen(NULL, RTLD_GLOBAL).
if (!filename)
handle = RTLD_DEFAULT;
#endif

if (LLVM_LIKELY(!IsProcess)) {
if (Find(Handle) != Handles.end()) {
if (CanClose)
DLClose(Handle);
return false;
}
Handles.push_back(Handle);
} else {
#ifndef LLVM_ON_WIN32
if (Process) {
if (CanClose)
DLClose(Process);
if (Process == Handle)
return false;
}
#endif
Process = Handle;
}
return true;
}
// If we've already loaded this library, dlclose() the handle in order to
// keep the internal refcount at +1.
if (!OpenedHandles->insert(handle).second)
dlclose(handle);

void *Lookup(const char *Symbol) {
// Process handle gets first try.
if (Process) {
if (void *Ptr = DLSym(Process, Symbol))
return Ptr;
#ifndef NDEBUG
for (void *Handle : Handles)
assert(!DLSym(Handle, Symbol) && "Symbol exists in non process handle");
#endif
} else {
// Iterate in reverse, so newer libraries/symbols override older.
for (auto &&I = Handles.rbegin(), E = Handles.rend(); I != E; ++I) {
if (void *Ptr = DLSym(*I, Symbol))
return Ptr;
}
}
return nullptr;
return DynamicLibrary(handle);
}

DynamicLibrary DynamicLibrary::addPermanentLibrary(void *handle,
std::string *errMsg) {
SmartScopedLock<true> lock(*SymbolsMutex);
// If we've already loaded this library, tell the caller.
if (!OpenedHandles->insert(handle).second) {
if (errMsg) *errMsg = "Library already loaded";
return DynamicLibrary();
}
};

namespace {
// Collection of symbol name/value pairs to be searched prior to any libraries.
static llvm::ManagedStatic<llvm::StringMap<void *>> ExplicitSymbols;
// Collection of known library handles.
static llvm::ManagedStatic<DynamicLibrary::HandleSet> OpenedHandles;
// Lock for ExplicitSymbols and OpenedHandles.
static llvm::ManagedStatic<llvm::sys::SmartMutex<true>> SymbolsMutex;
return DynamicLibrary(handle);
}

#ifdef LLVM_ON_WIN32

#include "Windows/DynamicLibrary.inc"
void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
if (!isValid())
return nullptr;
return dlsym(Data, symbolName);
}

#else

#include "Unix/DynamicLibrary.inc"

#endif

char DynamicLibrary::Invalid;
using namespace llvm;
using namespace llvm::sys;

namespace llvm {
void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
return DoSearch(SymbolName); // DynamicLibrary.inc
}
DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
std::string *errMsg) {
if (errMsg) *errMsg = "dlopen() not supported on this platform";
return DynamicLibrary();
}

void DynamicLibrary::AddSymbol(StringRef SymbolName, void *SymbolValue) {
SmartScopedLock<true> Lock(*SymbolsMutex);
(*ExplicitSymbols)[SymbolName] = SymbolValue;
void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
return NULL;
}

DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName,
std::string *Err) {
SmartScopedLock<true> Lock(*SymbolsMutex);
void *Handle = HandleSet::DLOpen(FileName, Err);
if (Handle != &Invalid)
OpenedHandles->AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
#endif

return DynamicLibrary(Handle);
namespace llvm {
void *SearchForAddressOfSpecialSymbol(const char* symbolName);
}

DynamicLibrary DynamicLibrary::addPermanentLibrary(void *Handle,
std::string *Err) {
void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
SmartScopedLock<true> Lock(*SymbolsMutex);
// If we've already loaded this library, tell the caller.
if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false))
*Err = "Library already loaded";

return DynamicLibrary(Handle);
}
// First check symbols added via AddSymbol().
if (ExplicitSymbols.isConstructed()) {
StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);

void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
if (!isValid())
return nullptr;
return HandleSet::DLSym(Data, SymbolName);
}
if (i != ExplicitSymbols->end())
return i->second;
}

void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
{
SmartScopedLock<true> Lock(*SymbolsMutex);
#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
// Now search the libraries.
if (OpenedHandles.isConstructed()) {
for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
E = OpenedHandles->end(); I != E; ++I) {
//lt_ptr ptr = lt_dlsym(*I, symbolName);
void *ptr = dlsym(*I, symbolName);
if (ptr) {
return ptr;
}
}
}
#endif

// First check symbols added via AddSymbol().
if (ExplicitSymbols.isConstructed()) {
StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
if (void *Result = llvm::SearchForAddressOfSpecialSymbol(symbolName))
return Result;

if (i != ExplicitSymbols->end())
return i->second;
}
// This macro returns the address of a well-known, explicit symbol
#define EXPLICIT_SYMBOL(SYM) \
if (!strcmp(symbolName, #SYM)) return &SYM

// Now search the libraries.
if (OpenedHandles.isConstructed()) {
if (void *Ptr = OpenedHandles->Lookup(SymbolName))
return Ptr;
}
// On linux we have a weird situation. The stderr/out/in symbols are both
// macros and global variables because of standards requirements. So, we
// boldly use the EXPLICIT_SYMBOL macro without checking for a #define first.
#if defined(__linux__) and !defined(__ANDROID__)
{
EXPLICIT_SYMBOL(stderr);
EXPLICIT_SYMBOL(stdout);
EXPLICIT_SYMBOL(stdin);
}
#else
// For everything else, we want to check to make sure the symbol isn't defined
// as a macro before using EXPLICIT_SYMBOL.
{
#ifndef stdin
EXPLICIT_SYMBOL(stdin);
#endif
#ifndef stdout
EXPLICIT_SYMBOL(stdout);
#endif
#ifndef stderr
EXPLICIT_SYMBOL(stderr);
#endif
}
#endif
#undef EXPLICIT_SYMBOL

return llvm::SearchForAddressOfSpecialSymbol(SymbolName);
return nullptr;
}

#endif // LLVM_ON_WIN32

//===----------------------------------------------------------------------===//
// C API.
//===----------------------------------------------------------------------===//

LLVMBool LLVMLoadLibraryPermanently(const char *Filename) {
LLVMBool LLVMLoadLibraryPermanently(const char* Filename) {
return llvm::sys::DynamicLibrary::LoadLibraryPermanently(Filename);
}

58 changes: 58 additions & 0 deletions llvm/lib/Support/SearchForAddressOfSpecialSymbol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//===- SearchForAddressOfSpecialSymbol.cpp - Function addresses -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file pulls the addresses of certain symbols out of the linker. It must
// include as few header files as possible because it declares the symbols as
// void*, which would conflict with the actual symbol type if any header
// declared it.
//
//===----------------------------------------------------------------------===//

#include <string.h>

// Must declare the symbols in the global namespace.
static void *DoSearch(const char* symbolName) {
#define EXPLICIT_SYMBOL(SYM) \
extern void *SYM; if (!strcmp(symbolName, #SYM)) return &SYM

// If this is darwin, it has some funky issues, try to solve them here. Some
// important symbols are marked 'private external' which doesn't allow
// SearchForAddressOfSymbol to find them. As such, we special case them here,
// there is only a small handful of them.

#ifdef __APPLE__
{
// __eprintf is sometimes used for assert() handling on x86.
//
// FIXME: Currently disabled when using Clang, as we don't always have our
// runtime support libraries available.
#ifndef __clang__
#ifdef __i386__
EXPLICIT_SYMBOL(__eprintf);
#endif
#endif
}
#endif

#ifdef __CYGWIN__
{
EXPLICIT_SYMBOL(_alloca);
EXPLICIT_SYMBOL(__main);
}
#endif

#undef EXPLICIT_SYMBOL
return nullptr;
}

namespace llvm {
void *SearchForAddressOfSpecialSymbol(const char* symbolName) {
return DoSearch(symbolName);
}
} // namespace llvm
131 changes: 0 additions & 131 deletions llvm/lib/Support/Unix/DynamicLibrary.inc

This file was deleted.

218 changes: 103 additions & 115 deletions llvm/lib/Support/Windows/DynamicLibrary.inc
Original file line number Diff line number Diff line change
@@ -12,139 +12,97 @@
//===----------------------------------------------------------------------===//

#include "WindowsSupport.h"
#include "llvm/Support/raw_ostream.h"

#include <Psapi.h>
#ifdef __MINGW32__
#include <imagehlp.h>
#else
#include <dbghelp.h>
#endif

#ifdef _MSC_VER
#include <ntverp.h>
#endif

namespace llvm {

//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only Win32 specific code
//=== and must not be UNIX code.
//===----------------------------------------------------------------------===//

typedef BOOL (WINAPI *fpEnumerateLoadedModules)(HANDLE,PENUMLOADED_MODULES_CALLBACK64,PVOID);
static fpEnumerateLoadedModules fEnumerateLoadedModules;
static llvm::ManagedStatic<DenseSet<HMODULE> > OpenedHandles;

DynamicLibrary::HandleSet::~HandleSet() {
for (void *Handle : Handles)
FreeLibrary(HMODULE(Handle));
static bool loadDebugHelp(void) {
HMODULE hLib = ::LoadLibraryW(L"Dbghelp.dll");
if (hLib) {
fEnumerateLoadedModules = (fpEnumerateLoadedModules)
::GetProcAddress(hLib, "EnumerateLoadedModules64");
}
return fEnumerateLoadedModules != 0;
}

// 'Process' should not be released on Windows.
assert((!Process || Process==this) && "Bad Handle");
static BOOL CALLBACK
ELM_Callback(PCSTR ModuleName, DWORD64 ModuleBase,
ULONG ModuleSize, PVOID UserContext) {
OpenedHandles->insert((HMODULE)ModuleBase);
return TRUE;
}

void *DynamicLibrary::HandleSet::DLOpen(const char *File, std::string *Err) {
// Create the instance and return it to be the *Process* handle
// simillar to dlopen(NULL, RTLD_LAZY|RTLD_GLOBAL)
if (!File)
return &(*OpenedHandles);
sys::DynamicLibrary
sys::DynamicLibrary::getPermanentLibrary(const char *filename,
std::string *errMsg) {
SmartScopedLock<true> lock(*SymbolsMutex);

if (!filename) {
// When no file is specified, enumerate all DLLs and EXEs in the process.
if (!fEnumerateLoadedModules) {
if (!loadDebugHelp()) {
assert(false && "These APIs should always be available");
return DynamicLibrary();
}
}

SmallVector<wchar_t, MAX_PATH> FileUnicode;
if (std::error_code ec = windows::UTF8ToUTF16(File, FileUnicode)) {
SetLastError(ec.value());
MakeErrMsg(Err, std::string(File) + ": Can't convert to UTF-16");
return &DynamicLibrary::Invalid;
fEnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
// Dummy library that represents "search all handles".
// This is mostly to ensure that the return value still shows up as "valid".
return DynamicLibrary(&OpenedHandles);
}

HMODULE Handle = LoadLibraryW(FileUnicode.data());
if (Handle == NULL) {
MakeErrMsg(Err, std::string(File) + ": Can't open");
return &DynamicLibrary::Invalid;
SmallVector<wchar_t, MAX_PATH> filenameUnicode;
if (std::error_code ec = windows::UTF8ToUTF16(filename, filenameUnicode)) {
SetLastError(ec.value());
MakeErrMsg(errMsg, std::string(filename) + ": Can't convert to UTF-16");
return DynamicLibrary();
}

return reinterpret_cast<void*>(Handle);
}
HMODULE a_handle = LoadLibraryW(filenameUnicode.data());

static DynamicLibrary::HandleSet *IsOpenedHandlesInstance(void *Handle) {
if (!OpenedHandles.isConstructed())
return nullptr;
DynamicLibrary::HandleSet &Inst = *OpenedHandles;
return Handle == &Inst ? &Inst : nullptr;
}
if (a_handle == 0) {
MakeErrMsg(errMsg, std::string(filename) + ": Can't open");
return DynamicLibrary();
}

void DynamicLibrary::HandleSet::DLClose(void *Handle) {
if (HandleSet* HS = IsOpenedHandlesInstance(Handle))
HS->Process = nullptr; // Just drop the *Process* handle.
else
FreeLibrary((HMODULE)Handle);
}
// If we've already loaded this library, FreeLibrary() the handle in order to
// keep the internal refcount at +1.
if (!OpenedHandles->insert(a_handle).second)
FreeLibrary(a_handle);

static bool GetProcessModules(HANDLE H, DWORD &Bytes, HMODULE *Data = nullptr) {
// EnumProcessModules will fail on Windows 64 while MingW-32 doesn't have
// EnumProcessModulesEx.
if (
#ifdef _WIN64
!EnumProcessModulesEx(H, Data, Bytes, &Bytes, LIST_MODULES_64BIT)
#else
!EnumProcessModules(H, Data, Bytes, &Bytes)
#endif
) {
std::string Err;
if (MakeErrMsg(&Err, "EnumProcessModules failure"))
llvm::errs() << Err << "\n";
return false;
}
return true;
return DynamicLibrary(a_handle);
}

void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
HandleSet* HS = IsOpenedHandlesInstance(Handle);
if (!HS)
return (void *)uintptr_t(GetProcAddress((HMODULE)Handle, Symbol));

// Could have done a dlclose on the *Process* handle
if (!HS->Process)
return nullptr;

// Trials indicate EnumProcessModulesEx is consistantly faster than using
// EnumerateLoadedModules64 or CreateToolhelp32Snapshot.
//
// | Handles | DbgHelp.dll | CreateSnapshot | EnumProcessModulesEx
// |=========|=============|========================================
// | 37 | 0.0000585 * | 0.0003031 | 0.0000152
// | 1020 | 0.0026310 * | 0.0121598 | 0.0002683
// | 2084 | 0.0149418 * | 0.0369936 | 0.0005610
//
// * Not including the load time of Dbghelp.dll (~.005 sec)
//
// There's still a case to somehow cache the result of EnumProcessModulesEx
// across invocations, but the complication of doing that properly...
// Possibly using LdrRegisterDllNotification to invalidate the cache?

DWORD Bytes = 0;
HMODULE Self = HMODULE(GetCurrentProcess());
if (!GetProcessModules(Self, Bytes))
return nullptr;

// Get the most recent list in case any modules added/removed between calls
// to EnumProcessModulesEx that gets the amount of, then copies the HMODULES.
// MSDN is pretty clear that if the module list changes during the call to
// EnumProcessModulesEx the results should not be used.
std::vector<HMODULE> Handles;
do {
assert(Bytes && ((Bytes % sizeof(HMODULE)) == 0) &&
"Should have at least one module and be aligned");
Handles.resize(Bytes / sizeof(HMODULE));
if (!GetProcessModules(Self, Bytes, Handles.data()))
return nullptr;
} while (Bytes != (Handles.size() * sizeof(HMODULE)));

// Try EXE first, mirroring what dlsym(dlopen(NULL)) does.
if (FARPROC Ptr = GetProcAddress(HMODULE(Handles.front()), Symbol))
return (void *) uintptr_t(Ptr);

if (Handles.size() > 1) {
// This is different behaviour than what Posix dlsym(dlopen(NULL)) does.
// Doing that here is causing real problems for the JIT where msvc.dll
// and ucrt.dll can define the same symbols. The runtime linker will choose
// symbols from ucrt.dll first, but iterating NOT in reverse here would
// mean that the msvc.dll versions would be returned.

for (auto I = Handles.rbegin(), E = Handles.rend()-1; I != E; ++I) {
if (FARPROC Ptr = GetProcAddress(HMODULE(*I), Symbol))
return (void *) uintptr_t(Ptr);
}
sys::DynamicLibrary
sys::DynamicLibrary::addPermanentLibrary(void *handle, std::string *errMsg) {
SmartScopedLock<true> lock(*SymbolsMutex);
// If we've already loaded this library, tell the caller.
if (!OpenedHandles->insert((HMODULE)handle).second) {
MakeErrMsg(errMsg, "Library already loaded");
return DynamicLibrary();
}
return nullptr;
}

return DynamicLibrary(handle);
}

// Stack probing routines are in the support library (e.g. libgcc), but we don't
// have dynamic linking on windows. Provide a hook.
@@ -171,18 +129,38 @@ void *DynamicLibrary::HandleSet::DLSym(void *Handle, const char *Symbol) {
#undef INLINE_DEF_SYMBOL1
#undef INLINE_DEF_SYMBOL2

static void *DoSearch(const char *SymbolName) {
void *sys::DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
SmartScopedLock<true> Lock(*SymbolsMutex);

// First check symbols added via AddSymbol().
if (ExplicitSymbols.isConstructed()) {
StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);

if (i != ExplicitSymbols->end())
return i->second;
}

// Now search the libraries.
if (OpenedHandles.isConstructed()) {
for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(),
E = OpenedHandles->end(); I != E; ++I) {
FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
if (ptr) {
return (void *)(intptr_t)ptr;
}
}
}

#define EXPLICIT_SYMBOL(SYM) \
if (!strcmp(SymbolName, #SYM)) \
if (!strcmp(symbolName, #SYM)) \
return (void *)&SYM;
#define EXPLICIT_SYMBOL2(SYMFROM, SYMTO) \
if (!strcmp(SymbolName, #SYMFROM)) \
if (!strcmp(symbolName, #SYMFROM)) \
return (void *)&SYMTO;

#ifdef _M_IX86
#define INLINE_DEF_SYMBOL1(TYP, SYM) \
if (!strcmp(SymbolName, #SYM)) \
if (!strcmp(symbolName, #SYM)) \
return (void *)&inline_##SYM;
#define INLINE_DEF_SYMBOL2(TYP, SYM) INLINE_DEF_SYMBOL1(TYP, SYM)
#endif
@@ -196,5 +174,15 @@ static void *DoSearch(const char *SymbolName) {
#undef INLINE_DEF_SYMBOL1
#undef INLINE_DEF_SYMBOL2

return nullptr;
return 0;
}

void *sys::DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
if (!isValid())
return NULL;
if (Data == &OpenedHandles)
return SearchForAddressOfSymbol(symbolName);
return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
}

}
2 changes: 0 additions & 2 deletions llvm/unittests/Support/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -67,5 +67,3 @@ add_llvm_unittest(SupportTests

# ManagedStatic.cpp uses <pthread>.
target_link_libraries(SupportTests ${LLVM_PTHREAD_LIB})

add_subdirectory(DynamicLibrary)
19 changes: 0 additions & 19 deletions llvm/unittests/Support/DynamicLibrary/CMakeLists.txt

This file was deleted.

133 changes: 0 additions & 133 deletions llvm/unittests/Support/DynamicLibrary/DynamicLibraryTest.cpp

This file was deleted.

36 changes: 0 additions & 36 deletions llvm/unittests/Support/DynamicLibrary/PipSqueak.cxx

This file was deleted.

19 changes: 0 additions & 19 deletions llvm/unittests/Support/DynamicLibrary/PipSqueak.h

This file was deleted.

0 comments on commit fd96d5e

Please sign in to comment.