Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkUnicode_icu_runtime.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
11
12#include <dlfcn.h>
13
14#define SK_RUNTIME_ICU_PATHS "libicuuc.so"
15
16std::unique_ptr<SkICULib> SkLoadICULib() {
17 static constexpr char const* gLibPaths[] = { SK_RUNTIME_ICU_PATHS };
18
19 void* dlhnd = nullptr;
20 for (const auto path : gLibPaths) {
21 dlhnd = dlopen(path, RTLD_LAZY);
22 if (dlhnd) {
23 break;
24 }
25 }
26
27 if (!dlhnd) {
28 SkDEBUGF("ICU loader: failed to open libicuuc.\n");
29 return nullptr;
30 }
31
32 int icu_ver = -1;
33
34 bool resolved_required_syms = true;
35
36 auto resolve_sym = [&](void* hnd, const char name[], bool required = false) -> void* {
37 static constexpr int kMinVer = 44,
38 kMaxVer = 100;
39
40 // First call performs a search to determine the actual lib version.
41 // Subsequent calls are pinned to the version found.
42 const auto search_to = icu_ver > 0 ? icu_ver : kMaxVer;
43 icu_ver = icu_ver > 0 ? icu_ver : kMinVer;
44
45 for (;;) {
46 const auto sym = SkStringPrintf("%s_%d", name, icu_ver);
47 if (auto* addr = dlsym(dlhnd, sym.c_str())) {
48 return addr;
49 }
50
51 if (icu_ver == search_to) {
52 break;
53 }
54
55 icu_ver++;
56 }
57
58 if (required) {
59 resolved_required_syms = false;
60 }
61 return nullptr;
62 };
63
64 SkICULib lib {};
65
66 // When using dlsym
67 // *(void**)(&procPtr) = dlsym(self, "proc");
68 // is non-standard, but safe for POSIX. Cannot write
69 // *reinterpret_cast<void**>(&procPtr) = dlsym(self, "proc");
70 // because clang has not implemented DR573. See http://clang.llvm.org/cxx_dr_status.html .
71 #define SKICU_FUNC(fname) *(void**)(&lib.f_##fname) = resolve_sym(dlhnd, #fname, true);
73
74 *(void**)(&lib.f_ubrk_clone_) = resolve_sym(dlhnd, "ubrk_clone");
75 *(void**)(&lib.f_ubrk_safeClone_) = resolve_sym(dlhnd, "ubrk_safeClone");
76 *(void**)(&lib.f_ubrk_getLocaleByType) = resolve_sym(dlhnd, "ubrk_getLocaleByType");
77
78 if (!resolved_required_syms || (!lib.f_ubrk_clone_ && !lib.f_ubrk_safeClone_)) {
79 SkDEBUGF("ICU loader: failed to resolve required symbols.");
80 dlclose(dlhnd);
81 return nullptr;
82 }
83
84 return std::make_unique<SkICULib>(lib);
85}
86
#define SkDEBUGF(...)
Definition SkDebug.h:24
SK_API SkString static SkString SkStringPrintf()
Definition SkString.h:287
#define SK_RUNTIME_ICU_PATHS
std::unique_ptr< SkICULib > SkLoadICULib()
#define SKICU_EMIT_FUNCS
const char * name
Definition fuchsia.cc:50