1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "repr/symbol/exported_symbol_set.h"
16
17 #include <cxxabi.h>
18
19 #include "repr/ir_representation.h"
20 #include "utils/stl_utils.h"
21 #include "utils/string_utils.h"
22
23
24 namespace header_checker {
25 namespace repr {
26
27
IsCppSymbol(const std::string & name)28 static inline bool IsCppSymbol(const std::string &name) {
29 return utils::StartsWith(name, "_Z");
30 }
31
32
AddFunction(const std::string & name,ElfSymbolIR::ElfSymbolBinding binding)33 void ExportedSymbolSet::AddFunction(const std::string &name,
34 ElfSymbolIR::ElfSymbolBinding binding) {
35 funcs_.emplace(name, ElfFunctionIR(name, binding));
36 }
37
38
AddVar(const std::string & name,ElfSymbolIR::ElfSymbolBinding binding)39 void ExportedSymbolSet::AddVar(const std::string &name,
40 ElfSymbolIR::ElfSymbolBinding binding) {
41 vars_.emplace(name, ElfObjectIR(name, binding));
42 }
43
44
HasSymbol(const std::string & name) const45 bool ExportedSymbolSet::HasSymbol(const std::string &name) const {
46 if (funcs_.find(name) != funcs_.end()) {
47 return true;
48 }
49
50 if (vars_.find(name) != vars_.end()) {
51 return true;
52 }
53
54 if (utils::HasMatchingGlobPattern(glob_patterns_, name.c_str())) {
55 return true;
56 }
57
58 if (IsCppSymbol(name) && HasDemangledCppSymbolsOrPatterns()) {
59 std::unique_ptr<char, utils::FreeDeleter> demangled_name_c_str(
60 abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr));
61
62 if (demangled_name_c_str) {
63 std::string_view demangled_name(demangled_name_c_str.get());
64
65 if (demangled_cpp_symbols_.find(demangled_name) !=
66 demangled_cpp_symbols_.end()) {
67 return true;
68 }
69
70 if (utils::HasMatchingGlobPattern(demangled_cpp_glob_patterns_,
71 demangled_name_c_str.get())) {
72 return true;
73 }
74 }
75 }
76
77 return false;
78 }
79
80
81 } // namespace repr
82 } // namespace header_checker
83