Home | History | Annotate | Download | only in include
      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