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 "repr/ir_representation.h"
18 #include "utils/stl_utils.h"
19 #include "utils/string_utils.h"
20
21 #include <fnmatch.h>
22 #include <cxxabi.h>
23
24
25 namespace header_checker {
26 namespace repr {
27
28
IsCppSymbol(const std::string & name)29 static inline bool IsCppSymbol(const std::string &name) {
30 return utils::StartsWith(name, "_Z");
31 }
32
33
HasMatchingGlobPattern(const ExportedSymbolSet::GlobPatternSet & patterns,const char * text)34 static inline bool HasMatchingGlobPattern(
35 const ExportedSymbolSet::GlobPatternSet &patterns, const char *text) {
36 for (auto &&pattern : patterns) {
37 if (fnmatch(pattern.c_str(), text, 0) == 0) {
38 return true;
39 }
40 }
41 return false;
42 }
43
44
HasMatchingGlobPattern(const ExportedSymbolSet::GlobPatternSet & patterns,const std::string & text)45 static inline bool HasMatchingGlobPattern(
46 const ExportedSymbolSet::GlobPatternSet &patterns,
47 const std::string &text) {
48 return HasMatchingGlobPattern(patterns, text.c_str());
49 }
50
51
AddFunction(const std::string & name,ElfSymbolIR::ElfSymbolBinding binding)52 void ExportedSymbolSet::AddFunction(const std::string &name,
53 ElfSymbolIR::ElfSymbolBinding binding) {
54 funcs_.emplace(name, ElfFunctionIR(name, binding));
55 }
56
57
AddVar(const std::string & name,ElfSymbolIR::ElfSymbolBinding binding)58 void ExportedSymbolSet::AddVar(const std::string &name,
59 ElfSymbolIR::ElfSymbolBinding binding) {
60 vars_.emplace(name, ElfObjectIR(name, binding));
61 }
62
63
HasSymbol(const std::string & name) const64 bool ExportedSymbolSet::HasSymbol(const std::string &name) const {
65 if (funcs_.find(name) != funcs_.end()) {
66 return true;
67 }
68
69 if (vars_.find(name) != vars_.end()) {
70 return true;
71 }
72
73 if (HasMatchingGlobPattern(glob_patterns_, name)) {
74 return true;
75 }
76
77 if (IsCppSymbol(name) && HasDemangledCppSymbolsOrPatterns()) {
78 std::unique_ptr<char, utils::FreeDeleter> demangled_name_c_str(
79 abi::__cxa_demangle(name.c_str(), nullptr, nullptr, nullptr));
80
81 if (demangled_name_c_str) {
82 std::string_view demangled_name(demangled_name_c_str.get());
83
84 if (demangled_cpp_symbols_.find(demangled_name) !=
85 demangled_cpp_symbols_.end()) {
86 return true;
87 }
88
89 if (HasMatchingGlobPattern(demangled_cpp_glob_patterns_,
90 demangled_name_c_str.get())) {
91 return true;
92 }
93 }
94 }
95
96 return false;
97 }
98
99
100 } // namespace repr
101 } // namespace header_checker
102