1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "DlHelp.h" 18 19 #include <stdbool.h> 20 21 #ifdef WIN32_LEAN_AND_MEAN 22 #include <stdio.h> 23 #include <windows.h> 24 #else 25 #include <dlfcn.h> 26 #endif 27 28 DlLibrary DlOpenLibrary(const char* filename) { 29 #ifdef _WIN32 30 return LoadLibrary(filename); 31 #else 32 // Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed. 33 // This is due to the fact that it is possible that some threads might have yet to finish 34 // exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is 35 // unloaded. 36 return dlopen(filename, RTLD_NOW | RTLD_NODELETE); 37 #endif 38 } 39 40 bool DlCloseLibrary(DlLibrary library) { 41 #ifdef _WIN32 42 return (FreeLibrary(library) == TRUE); 43 #else 44 return (dlclose(library) == 0); 45 #endif 46 } 47 48 DlSymbol DlGetSymbol(DlLibrary handle, const char* symbol) { 49 #ifdef _WIN32 50 return (DlSymbol) GetProcAddress(handle, symbol); 51 #else 52 return dlsym(handle, symbol); 53 #endif 54 } 55 56 const char* DlGetError() { 57 #ifdef _WIN32 58 static char buffer[256]; 59 60 DWORD cause = GetLastError(); 61 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; 62 DWORD length = FormatMessageA(flags, NULL, cause, 0, buffer, sizeof(buffer), NULL); 63 if (length == 0) { 64 snprintf(buffer, sizeof(buffer), 65 "Error %lu while retrieving message for error %lu", 66 GetLastError(), cause); 67 length = strlen(buffer); 68 } 69 70 // Trim trailing whitespace. 71 for (DWORD i = length - 1; i > 0; --i) { 72 if (!isspace(buffer[i])) { 73 break; 74 } 75 buffer[i] = '\0'; 76 } 77 78 return buffer; 79 #else 80 return dlerror(); 81 #endif 82 } 83