1 /*
2  * Copyright (C) 2021 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 #define LOG_TAG "DynamicCLDeps"
18 
19 #include "DynamicCLDeps.h"
20 
21 #include <android-base/logging.h>
22 #include <dlfcn.h>
23 
24 namespace android::nn {
25 namespace {
26 
loadFunction(void * handle,const char * name)27 void* loadFunction(void* handle, const char* name) {
28     CHECK(handle != nullptr);
29     void* fn = dlsym(handle, name);
30     CHECK(fn != nullptr) << "Unable to open function " << name << ": " << dlerror();
31     return fn;
32 }
33 
34 #define NN_LOAD_FUNCTION(name, symbol) \
35     impl.name = reinterpret_cast<decltype(impl.name)>(loadFunction(handle, #symbol));
36 
loadCompatibilityLayerMemoryHelper()37 const CompatibilityLayerMemory loadCompatibilityLayerMemoryHelper() {
38     CompatibilityLayerMemory impl = {};
39 
40     // libandroid.so is NOT accessible for non-NDK apps and
41     // libcutils.so  is NOT accessible for NDK apps.
42     // Hence we try to load one or the other in order to cover both cases.
43     void* handle = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL);
44     if (handle != nullptr) {
45         NN_LOAD_FUNCTION(create, ASharedMemory_create);
46         NN_LOAD_FUNCTION(getSize, ASharedMemory_getSize);
47     } else {
48         handle = dlopen("libcutils.so", RTLD_LAZY | RTLD_LOCAL);
49         CHECK(handle != nullptr) << "Unable to open either libandroid.so or libcutils.so: "
50                                  << dlerror();
51         NN_LOAD_FUNCTION(create, ashmem_create_region);
52         NN_LOAD_FUNCTION(getSize, ashmem_get_size_region);
53     }
54 
55     return impl;
56 }
57 
58 #undef NN_LOAD_FUNCTION
59 
60 }  // namespace
61 
loadCompatibilityLayerMemory()62 const CompatibilityLayerMemory& loadCompatibilityLayerMemory() {
63     static const CompatibilityLayerMemory impl = loadCompatibilityLayerMemoryHelper();
64     return impl;
65 }
66 
67 }  // namespace android::nn
68