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