1 // Copyright (C) 2016 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 "abi_diff_wrappers.h"
16 
17 #pragma clang diagnostic push
18 #pragma clang diagnostic ignored "-Wunused-parameter"
19 #pragma clang diagnostic ignored "-Wnested-anon-types"
20 #include "proto/abi_dump.pb.h"
21 #include "proto/abi_diff.pb.h"
22 #pragma clang diagnostic pop
23 
24 #include <memory>
25 #include <fstream>
26 #include <iostream>
27 #include <string>
28 #include <vector>
29 
30 
31 typedef abi_diff::CompatibilityStatus CompatibilityStatus;
32 
33 class HeaderAbiDiff {
34  public:
HeaderAbiDiff(const std::string & lib_name,const std::string & arch,const std::string & old_dump,const std::string & new_dump,const std::string & compatibility_report,const std::set<std::string> & ignored_symbols)35   HeaderAbiDiff(const std::string &lib_name, const std::string &arch,
36                 const std::string &old_dump, const std::string &new_dump,
37                 const std::string &compatibility_report,
38                 const std::set<std::string> &ignored_symbols)
39       : lib_name_(lib_name), arch_(arch), old_dump_(old_dump),
40         new_dump_(new_dump), cr_(compatibility_report),
41       ignored_symbols_(ignored_symbols) { }
42 
43   CompatibilityStatus GenerateCompatibilityReport();
44 
45  private:
46   CompatibilityStatus CompareTUs(const abi_dump::TranslationUnit &old_tu,
47                                  const abi_dump::TranslationUnit &new_tu);
48   // Collect* methods fill in the diff_tu.
49   template <typename T, typename TDiff>
50   static CompatibilityStatus Collect(
51       google::protobuf::RepeatedPtrField<T> *elements_added,
52       google::protobuf::RepeatedPtrField<T> *elements_removed,
53       google::protobuf::RepeatedPtrField<TDiff> *elements_diff,
54       const google::protobuf::RepeatedPtrField<T> &old_srcs,
55       const google::protobuf::RepeatedPtrField<T> &new_srcs,
56       const std::set<std::string> &ignored_symbols);
57 
58   template <typename T>
59   static inline void AddToMap(std::map<std::string, const T *> *dst,
60                               const google::protobuf::RepeatedPtrField<T> &src);
61 
62   template <typename T>
63   static bool PopulateRemovedElements(
64       google::protobuf::RepeatedPtrField<T> *dst,
65       const std::map<std::string, const T *> &old_elements_map,
66       const std::map<std::string, const T *> &new_elements_map,
67       const std::set<std::string> &ignored_symbols);
68 
69   template <typename T, typename TDiff>
70   static bool PopulateCommonElements(
71       google::protobuf::RepeatedPtrField<TDiff> *dst,
72       const std::map<std::string, const T *> &old_elements_map,
73       const std::map<std::string, const T *> &new_elements_map,
74       const std::set<std::string> &ignored_symbols);
75 
76   template <typename T, typename TDiff>
77   static bool DumpDiffElements(
78       google::protobuf::RepeatedPtrField<TDiff> *dst,
79       std::vector<std::pair<const T *, const T *>> &pairs,
80       const std::set<std::string> &ignored_symbols);
81 
82   template <typename T>
83   static bool DumpLoneElements(google::protobuf::RepeatedPtrField<T> *dst,
84                                std::vector<const T *> &elements,
85                                const std::set<std::string> &ignored_symbols);
86 
87  private:
88   const std::string &lib_name_;
89   const std::string &arch_;
90   const std::string &old_dump_;
91   const std::string &new_dump_;
92   const std::string &cr_;
93   const std::set<std::string> &ignored_symbols_;
94 };
95 
96 template <typename T>
AddToMap(std::map<std::string,const T * > * dst,const google::protobuf::RepeatedPtrField<T> & src)97 inline void HeaderAbiDiff::AddToMap(
98     std::map<std::string, const T *> *dst,
99     const google::protobuf::RepeatedPtrField<T> &src) {
100   for (auto &&element : src) {
101     dst->insert(std::make_pair(element.basic_abi().linker_set_key(), &element));
102   }
103 }
104 
105 static inline CompatibilityStatus operator|(CompatibilityStatus f,
106                                             CompatibilityStatus s) {
107   return static_cast<CompatibilityStatus>(
108       static_cast<std::underlying_type<CompatibilityStatus>::type>(f) |
109       static_cast<std::underlying_type<CompatibilityStatus>::type>(s));
110 }
111 
112 static inline CompatibilityStatus operator&(
113     CompatibilityStatus f, CompatibilityStatus s) {
114   return static_cast<CompatibilityStatus>(
115       static_cast<std::underlying_type<CompatibilityStatus>::type>(f) &
116       static_cast<std::underlying_type<CompatibilityStatus>::type>(s));
117 }
118