• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2011 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/native_library.h"
6
7#include <dlfcn.h>
8#include <mach-o/getsect.h>
9
10#include <string_view>
11
12#include "base/apple/foundation_util.h"
13#include "base/apple/scoped_cftyperef.h"
14#include "base/files/file_path.h"
15#include "base/files/file_util.h"
16#include "base/logging.h"
17#include "base/strings/strcat.h"
18#include "base/strings/string_util.h"
19#include "base/strings/sys_string_conversions.h"
20#include "base/strings/utf_string_conversions.h"
21#include "base/threading/thread_restrictions.h"
22
23namespace base {
24
25std::string NativeLibraryLoadError::ToString() const {
26  return message;
27}
28
29NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path,
30                                           const NativeLibraryOptions& options,
31                                           NativeLibraryLoadError* error) {
32  // dlopen() etc. open the file off disk.
33  if (library_path.Extension() == "dylib" || !DirectoryExists(library_path)) {
34    void* dylib = dlopen(library_path.value().c_str(), RTLD_LAZY);
35    if (!dylib) {
36      if (error) {
37        error->message = dlerror();
38      }
39      return nullptr;
40    }
41    NativeLibrary native_lib = new NativeLibraryStruct();
42    native_lib->type = DYNAMIC_LIB;
43    native_lib->dylib = dylib;
44    return native_lib;
45  }
46  apple::ScopedCFTypeRef<CFURLRef> url = apple::FilePathToCFURL(library_path);
47  if (!url) {
48    return nullptr;
49  }
50  CFBundleRef bundle = CFBundleCreate(kCFAllocatorDefault, url.get());
51  if (!bundle) {
52    return nullptr;
53  }
54
55  NativeLibrary native_lib = new NativeLibraryStruct();
56  native_lib->type = BUNDLE;
57  native_lib->bundle = bundle;
58  return native_lib;
59}
60
61void UnloadNativeLibrary(NativeLibrary library) {
62  if (library->type == BUNDLE) {
63    CFRelease(library->bundle);
64  } else {
65    dlclose(library->dylib);
66  }
67  delete library;
68}
69
70void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
71                                          const char* name) {
72  // Get the function pointer using the right API for the type.
73  if (library->type == BUNDLE) {
74    apple::ScopedCFTypeRef<CFStringRef> symbol_name =
75        SysUTF8ToCFStringRef(name);
76    return CFBundleGetFunctionPointerForName(library->bundle,
77                                             symbol_name.get());
78  }
79
80  return dlsym(library->dylib, name);
81}
82
83std::string GetNativeLibraryName(std::string_view name) {
84  DCHECK(IsStringASCII(name));
85#if BUILDFLAG(IS_IOS)
86  // Returns mylib.framework/mylib
87  return FilePath()
88      .Append(name)
89      .AddExtension("framework")
90      .Append(name)
91      .value();
92#else
93  return StrCat({"lib", name, ".dylib"});
94#endif
95}
96
97std::string GetLoadableModuleName(std::string_view name) {
98  DCHECK(IsStringASCII(name));
99#if BUILDFLAG(IS_IOS)
100  // Returns mylib.framework
101  return FilePath()
102      .Append(name)
103      .AddExtension("framework")
104      .value();
105#else
106  return StrCat({name, ".so"});
107#endif
108}
109
110}  // namespace base
111