1 // Copyright (C) 2017 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 <llvm/Object/ELFObjectFile.h> 16 #include <llvm/Object/ELFTypes.h> 17 #include <llvm/Object/SymbolSize.h> 18 #include <llvm/Support/Endian.h> 19 #include <llvm/Support/raw_ostream.h> 20 21 #include <regex> 22 #include <set> 23 #include <string> 24 #include <vector> 25 26 using llvm::object::ObjectFile; 27 using llvm::object::ELFObjectFile; 28 using llvm::object::ELFFile; 29 using llvm::object::ELFType; 30 using llvm::object::ELFDataTypeTypedefHelper; 31 32 namespace abi_util { 33 34 std::set<std::string> CollectAllExportedHeaders( 35 const std::vector<std::string> &exported_header_dirs); 36 37 class VersionScriptParser { 38 public: 39 40 enum LineScope { 41 global, 42 local, 43 }; 44 45 VersionScriptParser(const std::string &version_script, 46 const std::string &arch, 47 const std::string &api); 48 bool Parse(); 49 50 const std::set<std::string> &GetFunctions(); 51 52 const std::set<std::string> &GetGlobVars(); 53 54 const std::set<std::string> &GetFunctionRegexs(); 55 56 const std::set<std::string> &GetGlobVarRegexs(); 57 58 private: 59 60 bool ParseInnerBlock(std::ifstream &symbol_ifstream); 61 62 LineScope GetLineScope(std::string &line, LineScope scope); 63 64 bool ParseSymbolLine(const std::string &line); 65 66 bool SymbolInArchAndApiVersion(const std::string &line, 67 const std::string &arch, int api); 68 69 bool SymbolExported(const std::string &line, const std::string &arch, 70 int api); 71 72 int ApiStrToInt(const std::string &api); 73 74 void AddToVars(std::string &symbol); 75 76 void AddToFunctions(std::string &symbol); 77 78 private: 79 const std::string &version_script_; 80 const std::string &arch_; 81 std::set<std::string> functions_; 82 std::set<std::string> globvars_; 83 // Added to speed up version script parsing and linking. 84 std::set<std::string> function_regexs_; 85 std::set<std::string> globvar_regexs_; 86 int api_; 87 }; 88 89 inline std::string FindAndReplace(const std::string &candidate_str, 90 const std::string &find_str, 91 const std::string &replace_str) { 92 // Find all matches of find_str in candidate_str and return a new string with 93 // all the matches replaced with replace_str 94 std::regex match_expr(find_str); 95 return std::regex_replace(candidate_str, match_expr, replace_str); 96 } 97 98 99 class SoFileParser { 100 public: 101 static std::unique_ptr<SoFileParser> Create(const ObjectFile *obj); 102 virtual const std::set<std::string> &GetFunctions() const = 0; 103 virtual const std::set<std::string> &GetGlobVars() const = 0; 104 virtual ~SoFileParser() {}; 105 virtual void GetSymbols() = 0; 106 }; 107 108 template<typename T> 109 class ELFSoFileParser : public SoFileParser { 110 public: 111 const std::set<std::string> &GetFunctions() const override; 112 113 const std::set<std::string> &GetGlobVars() const override; 114 115 LLVM_ELF_IMPORT_TYPES_ELFT(T) 116 typedef ELFFile<T> ELFO; 117 typedef typename ELFO::Elf_Sym Elf_Sym; 118 119 ELFSoFileParser(const ELFObjectFile<T> *obj) : obj_(obj) {} 120 virtual ~ELFSoFileParser() override {}; 121 void GetSymbols() override; 122 private: 123 const ELFObjectFile<T> *obj_; 124 std::set<std::string> functions_; 125 std::set<std::string> globvars_; 126 127 private: 128 bool IsSymbolExported(const Elf_Sym *elf_sym) const; 129 }; 130 131 } // namespace abi_util 132