Skip to content

Commit 3979966

Browse files
committed
Move shared object code into DlHelp.{h,c}
Bug: 151443957 Test: m & boot Change-Id: I85039aee69907c2375bd4e1d6f229ae566062149
1 parent ddc5ba1 commit 3979966

File tree

4 files changed

+126
-46
lines changed

4 files changed

+126
-46
lines changed

Android.bp

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ cc_library {
7171
name: "libnativehelper",
7272
host_supported: true,
7373
srcs: [
74+
"DlHelp.c",
7475
"JNIHelp.cpp",
7576
"JniConstants.cpp",
7677
"JniInvocation.cpp",
@@ -128,6 +129,7 @@ cc_library_shared {
128129
"platform_include",
129130
],
130131
srcs: [
132+
"DlHelp.c",
131133
"JNIHelp.cpp",
132134
"JniConstants.cpp",
133135
],

DlHelp.c

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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+
}

DlHelp.h

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
#pragma once
18+
19+
#include <sys/cdefs.h>
20+
#include <stdbool.h>
21+
22+
__BEGIN_DECLS
23+
24+
typedef void* DlLibrary;
25+
typedef void* DlSymbol;
26+
27+
DlLibrary DlOpenLibrary(const char* filename);
28+
bool DlCloseLibrary(DlLibrary library);
29+
DlSymbol DlGetSymbol(DlLibrary library, const char* symbol);
30+
const char* DlGetError();
31+
32+
__END_DECLS

JniInvocation.cpp

+10-46
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <android-base/errors.h>
3434
#endif
3535

36+
#include "DlHelp.h"
3637
#include "JniConstants.h"
3738

3839
namespace {
@@ -65,43 +66,6 @@ int GetLibrarySystemProperty(char* buffer) {
6566
#define FUNC_POINTER void*
6667
#endif
6768

68-
void* OpenLibrary(const char* filename) {
69-
#ifdef _WIN32
70-
return LoadLibrary(filename);
71-
#else
72-
// Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed.
73-
// This is due to the fact that it is possible that some threads might have yet to finish
74-
// exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is
75-
// unloaded.
76-
const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;
77-
return dlopen(filename, kDlopenFlags);
78-
#endif
79-
}
80-
81-
int CloseLibrary(void* handle) {
82-
#ifdef _WIN32
83-
return FreeLibrary(static_cast<HMODULE>(handle));
84-
#else
85-
return dlclose(handle);
86-
#endif
87-
}
88-
89-
FUNC_POINTER GetSymbol(void* handle, const char* symbol) {
90-
#ifdef _WIN32
91-
return GetProcAddress(static_cast<HMODULE>(handle), symbol);
92-
#else
93-
return dlsym(handle, symbol);
94-
#endif
95-
}
96-
97-
std::string GetError() {
98-
#ifdef _WIN32
99-
return android::base::SystemErrorCodeToString(GetLastError());
100-
#else
101-
return std::string(dlerror());
102-
#endif
103-
}
104-
10569
} // namespace
10670

10771
struct JniInvocationImpl final {
@@ -158,7 +122,7 @@ JniInvocationImpl::JniInvocationImpl() :
158122
JniInvocationImpl::~JniInvocationImpl() {
159123
jni_invocation_ = NULL;
160124
if (handle_ != NULL) {
161-
CloseLibrary(handle_);
125+
DlCloseLibrary(handle_);
162126
}
163127
}
164128

@@ -213,11 +177,11 @@ bool JniInvocationImpl::Init(const char* library) {
213177
char* buffer = NULL;
214178
#endif
215179
library = GetLibrary(library, buffer);
216-
handle_ = OpenLibrary(library);
180+
handle_ = DlOpenLibrary(library);
217181
if (handle_ == NULL) {
218182
if (strcmp(library, kLibraryFallback) == 0) {
219183
// Nothing else to try.
220-
ALOGE("Failed to dlopen %s: %s", library, GetError().c_str());
184+
ALOGE("Failed to dlopen %s: %s", library, DlGetError());
221185
return false;
222186
}
223187
// Note that this is enough to get something like the zygote
@@ -226,11 +190,11 @@ bool JniInvocationImpl::Init(const char* library) {
226190
// RuntimeInit.commonInit for where we fix up the property to
227191
// avoid future fallbacks. http://b/11463182
228192
ALOGW("Falling back from %s to %s after dlopen error: %s",
229-
library, kLibraryFallback, GetError().c_str());
193+
library, kLibraryFallback, DlGetError());
230194
library = kLibraryFallback;
231-
handle_ = OpenLibrary(library);
195+
handle_ = DlOpenLibrary(library);
232196
if (handle_ == NULL) {
233-
ALOGE("Failed to dlopen %s: %s", library, GetError().c_str());
197+
ALOGE("Failed to dlopen %s: %s", library, DlGetError());
234198
return false;
235199
}
236200
}
@@ -262,10 +226,10 @@ jint JniInvocationImpl::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* v
262226
}
263227

264228
bool JniInvocationImpl::FindSymbol(FUNC_POINTER* pointer, const char* symbol) {
265-
*pointer = GetSymbol(handle_, symbol);
229+
*pointer = reinterpret_cast<FUNC_POINTER>(DlGetSymbol(handle_, symbol));
266230
if (*pointer == NULL) {
267-
ALOGE("Failed to find symbol %s: %s\n", symbol, GetError().c_str());
268-
CloseLibrary(handle_);
231+
ALOGE("Failed to find symbol %s: %s\n", symbol, DlGetError());
232+
DlCloseLibrary(handle_);
269233
handle_ = NULL;
270234
return false;
271235
}

0 commit comments

Comments
 (0)