michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "GLLibraryLoader.h" michael@0: michael@0: #include "nsDebug.h" michael@0: michael@0: namespace mozilla { michael@0: namespace gl { michael@0: michael@0: bool michael@0: GLLibraryLoader::OpenLibrary(const char *library) michael@0: { michael@0: PRLibSpec lspec; michael@0: lspec.type = PR_LibSpec_Pathname; michael@0: lspec.value.pathname = library; michael@0: michael@0: mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL); michael@0: if (!mLibrary) michael@0: return false; michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool michael@0: GLLibraryLoader::LoadSymbols(SymLoadStruct *firstStruct, michael@0: bool tryplatform, michael@0: const char *prefix, michael@0: bool warnOnFailure) michael@0: { michael@0: return LoadSymbols(mLibrary, michael@0: firstStruct, michael@0: tryplatform ? mLookupFunc : nullptr, michael@0: prefix, michael@0: warnOnFailure); michael@0: } michael@0: michael@0: PRFuncPtr michael@0: GLLibraryLoader::LookupSymbol(PRLibrary *lib, michael@0: const char *sym, michael@0: PlatformLookupFunction lookupFunction) michael@0: { michael@0: PRFuncPtr res = 0; michael@0: michael@0: // try finding it in the library directly, if we have one michael@0: if (lib) { michael@0: res = PR_FindFunctionSymbol(lib, sym); michael@0: } michael@0: michael@0: // then try looking it up via the lookup symbol michael@0: if (!res && lookupFunction) { michael@0: res = lookupFunction(sym); michael@0: } michael@0: michael@0: // finally just try finding it in the process michael@0: if (!res) { michael@0: PRLibrary *leakedLibRef; michael@0: res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef); michael@0: } michael@0: michael@0: return res; michael@0: } michael@0: michael@0: bool michael@0: GLLibraryLoader::LoadSymbols(PRLibrary *lib, michael@0: SymLoadStruct *firstStruct, michael@0: PlatformLookupFunction lookupFunction, michael@0: const char *prefix, michael@0: bool warnOnFailure) michael@0: { michael@0: char sbuf[MAX_SYMBOL_LENGTH * 2]; michael@0: int failCount = 0; michael@0: michael@0: SymLoadStruct *ss = firstStruct; michael@0: while (ss->symPointer) { michael@0: *ss->symPointer = 0; michael@0: michael@0: for (int i = 0; i < MAX_SYMBOL_NAMES; i++) { michael@0: if (ss->symNames[i] == nullptr) michael@0: break; michael@0: michael@0: const char *s = ss->symNames[i]; michael@0: if (prefix && *prefix != 0) { michael@0: strcpy(sbuf, prefix); michael@0: strcat(sbuf, ss->symNames[i]); michael@0: s = sbuf; michael@0: } michael@0: michael@0: PRFuncPtr p = LookupSymbol(lib, s, lookupFunction); michael@0: if (p) { michael@0: *ss->symPointer = p; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: if (*ss->symPointer == 0) { michael@0: if (warnOnFailure) michael@0: printf_stderr("Can't find symbol '%s'.\n", ss->symNames[0]); michael@0: michael@0: failCount++; michael@0: } michael@0: michael@0: ss++; michael@0: } michael@0: michael@0: return failCount == 0 ? true : false; michael@0: } michael@0: michael@0: } /* namespace gl */ michael@0: } /* namespace mozilla */ michael@0: