xref: /aosp_15_r20/external/cronet/base/native_library_fuchsia.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/native_library.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <fcntl.h>
8*6777b538SAndroid Build Coastguard Worker #include <fuchsia/io/cpp/fidl.h>
9*6777b538SAndroid Build Coastguard Worker #include <lib/fdio/directory.h>
10*6777b538SAndroid Build Coastguard Worker #include <lib/fdio/io.h>
11*6777b538SAndroid Build Coastguard Worker #include <lib/zx/vmo.h>
12*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
13*6777b538SAndroid Build Coastguard Worker #include <zircon/dlfcn.h>
14*6777b538SAndroid Build Coastguard Worker #include <zircon/status.h>
15*6777b538SAndroid Build Coastguard Worker #include <zircon/syscalls.h>
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker #include "base/base_paths.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/posix/safe_strerror.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/strings/strcat.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
29*6777b538SAndroid Build Coastguard Worker #include "base_paths.h"
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker namespace base {
32*6777b538SAndroid Build Coastguard Worker 
ToString() const33*6777b538SAndroid Build Coastguard Worker std::string NativeLibraryLoadError::ToString() const {
34*6777b538SAndroid Build Coastguard Worker   return message;
35*6777b538SAndroid Build Coastguard Worker }
36*6777b538SAndroid Build Coastguard Worker 
LoadNativeLibraryWithOptions(const FilePath & library_path,const NativeLibraryOptions & options,NativeLibraryLoadError * error)37*6777b538SAndroid Build Coastguard Worker NativeLibrary LoadNativeLibraryWithOptions(const FilePath& library_path,
38*6777b538SAndroid Build Coastguard Worker                                            const NativeLibraryOptions& options,
39*6777b538SAndroid Build Coastguard Worker                                            NativeLibraryLoadError* error) {
40*6777b538SAndroid Build Coastguard Worker   FilePath computed_path;
41*6777b538SAndroid Build Coastguard Worker   FilePath library_root_path =
42*6777b538SAndroid Build Coastguard Worker       base::PathService::CheckedGet(DIR_ASSETS).Append("lib");
43*6777b538SAndroid Build Coastguard Worker   if (library_path.IsAbsolute()) {
44*6777b538SAndroid Build Coastguard Worker     // See more info in fxbug.dev/105910.
45*6777b538SAndroid Build Coastguard Worker     if (!library_root_path.IsParent(library_path)) {
46*6777b538SAndroid Build Coastguard Worker       auto error_message =
47*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("Absolute library paths must begin with %s",
48*6777b538SAndroid Build Coastguard Worker                              library_root_path.value().c_str());
49*6777b538SAndroid Build Coastguard Worker       DLOG(ERROR) << error_message;
50*6777b538SAndroid Build Coastguard Worker       if (error) {
51*6777b538SAndroid Build Coastguard Worker         error->message = std::move(error_message);
52*6777b538SAndroid Build Coastguard Worker       }
53*6777b538SAndroid Build Coastguard Worker       return nullptr;
54*6777b538SAndroid Build Coastguard Worker     }
55*6777b538SAndroid Build Coastguard Worker     computed_path = library_path;
56*6777b538SAndroid Build Coastguard Worker   } else {
57*6777b538SAndroid Build Coastguard Worker     computed_path = library_root_path.Append(library_path);
58*6777b538SAndroid Build Coastguard Worker   }
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker   // Use fdio_open_fd (a Fuchsia-specific API) here so we can pass the
61*6777b538SAndroid Build Coastguard Worker   // appropriate FS rights flags to request executability.
62*6777b538SAndroid Build Coastguard Worker   // TODO(crbug.com/1018538): Teach base::File about FLAG_WIN_EXECUTE on
63*6777b538SAndroid Build Coastguard Worker   // Fuchsia, and then use it here instead of using fdio_open_fd() directly.
64*6777b538SAndroid Build Coastguard Worker   base::ScopedFD fd;
65*6777b538SAndroid Build Coastguard Worker   zx_status_t status = fdio_open_fd(
66*6777b538SAndroid Build Coastguard Worker       computed_path.value().c_str(),
67*6777b538SAndroid Build Coastguard Worker       static_cast<uint32_t>(fuchsia::io::OpenFlags::RIGHT_READABLE |
68*6777b538SAndroid Build Coastguard Worker                             fuchsia::io::OpenFlags::RIGHT_EXECUTABLE),
69*6777b538SAndroid Build Coastguard Worker       base::ScopedFD::Receiver(fd).get());
70*6777b538SAndroid Build Coastguard Worker   if (status != ZX_OK) {
71*6777b538SAndroid Build Coastguard Worker     if (error) {
72*6777b538SAndroid Build Coastguard Worker       error->message =
73*6777b538SAndroid Build Coastguard Worker           base::StringPrintf("fdio_open_fd: %s", zx_status_get_string(status));
74*6777b538SAndroid Build Coastguard Worker     }
75*6777b538SAndroid Build Coastguard Worker     return nullptr;
76*6777b538SAndroid Build Coastguard Worker   }
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   zx::vmo vmo;
79*6777b538SAndroid Build Coastguard Worker   status = fdio_get_vmo_exec(fd.get(), vmo.reset_and_get_address());
80*6777b538SAndroid Build Coastguard Worker   if (status != ZX_OK) {
81*6777b538SAndroid Build Coastguard Worker     if (error) {
82*6777b538SAndroid Build Coastguard Worker       error->message = base::StringPrintf("fdio_get_vmo_exec: %s",
83*6777b538SAndroid Build Coastguard Worker                                           zx_status_get_string(status));
84*6777b538SAndroid Build Coastguard Worker     }
85*6777b538SAndroid Build Coastguard Worker     return nullptr;
86*6777b538SAndroid Build Coastguard Worker   }
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   NativeLibrary result = dlopen_vmo(vmo.get(), RTLD_LAZY | RTLD_LOCAL);
89*6777b538SAndroid Build Coastguard Worker   return result;
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker 
UnloadNativeLibrary(NativeLibrary library)92*6777b538SAndroid Build Coastguard Worker void UnloadNativeLibrary(NativeLibrary library) {
93*6777b538SAndroid Build Coastguard Worker   // dlclose() is a no-op on Fuchsia, so do nothing here.
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker 
GetFunctionPointerFromNativeLibrary(NativeLibrary library,const char * name)96*6777b538SAndroid Build Coastguard Worker void* GetFunctionPointerFromNativeLibrary(NativeLibrary library,
97*6777b538SAndroid Build Coastguard Worker                                           const char* name) {
98*6777b538SAndroid Build Coastguard Worker   return dlsym(library, name);
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
GetNativeLibraryName(StringPiece name)101*6777b538SAndroid Build Coastguard Worker std::string GetNativeLibraryName(StringPiece name) {
102*6777b538SAndroid Build Coastguard Worker   return StrCat({"lib", name, ".so"});
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker 
GetLoadableModuleName(StringPiece name)105*6777b538SAndroid Build Coastguard Worker std::string GetLoadableModuleName(StringPiece name) {
106*6777b538SAndroid Build Coastguard Worker   return GetNativeLibraryName(name);
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker }  // namespace base
110