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