1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 2 // -*- Mode: C++ -*- 3 // 4 // Copyright (C) 2013-2021 Red Hat, Inc. 5 6 ///@file 7 8 #ifndef __ABG_TOOLS_UTILS_H 9 #define __ABG_TOOLS_UTILS_H 10 11 #include <iostream> 12 #include <istream> 13 #include <memory> 14 #include <ostream> 15 #include <set> 16 #include <string> 17 #include "abg-suppression.h" 18 19 namespace abigail 20 { 21 22 namespace tools_utils 23 { 24 25 using std::ostream; 26 using std::istream; 27 using std::ifstream; 28 using std::string; 29 using std::set; 30 using std::shared_ptr; 31 32 const char* get_system_libdir(); 33 const char* get_anonymous_struct_internal_name_prefix(); 34 const char* get_anonymous_union_internal_name_prefix(); 35 const char* get_anonymous_enum_internal_name_prefix(); 36 37 bool file_exists(const string&); 38 bool is_regular_file(const string&); 39 bool is_dir(const string&); 40 bool dir_exists(const string&); 41 bool dir_is_empty(const string &); 42 bool decl_names_equal(const string&, const string&); 43 bool maybe_get_symlink_target_file_path(const string& file_path, 44 string& target_path); 45 bool base_name(string const& path, 46 string& file_name); 47 bool dir_name(string const &path, 48 string& path_dir_name, 49 bool keep_separator_at_end=false); 50 void real_path(const string&path, string& realpath); 51 bool ensure_dir_path_created(const string&); 52 bool ensure_parent_dir_created(const string&); 53 ostream& emit_prefix(const string& prog_name, ostream& out); 54 bool check_file(const string& path, ostream& out, const string& prog_name = ""); 55 bool check_dir(const string& path, ostream& out, const string& prog_name=""); 56 bool string_ends_with(const string&, const string&); 57 bool string_begins_with(const string&, const string&); 58 bool string_is_ascii(const string&); 59 bool string_is_ascii_identifier(const string&); 60 bool split_string(const string&, const string&, vector<string>&); 61 bool string_suffix(const string&, const string&, string&); 62 bool sorted_strings_common_prefix(vector<string>&, string&); 63 string get_library_version_string(); 64 string get_abixml_version_string(); 65 bool execute_command_and_get_output(const string&, vector<string>&); 66 bool get_dsos_provided_by_rpm(const string& rpm_path, 67 set<string>& provided_dsos); 68 string trim_white_space(const string&); 69 string trim_leading_string(const string& from, const string& to_trim); 70 void convert_char_stars_to_char_star_stars(const vector<char*>&, 71 vector<char**>&); 72 73 suppr::type_suppression_sptr 74 gen_suppr_spec_from_headers(const string& hdrs_root_dir); 75 76 suppr::type_suppression_sptr 77 gen_suppr_spec_from_headers(const string& hdrs_root_dir, 78 const vector<string>& hdr_files); 79 80 suppr::type_suppression_sptr 81 gen_suppr_spec_from_headers(const vector<string>& headers_root_dirs, 82 const vector<string>& header_files); 83 84 suppr::suppressions_type 85 gen_suppr_spec_from_kernel_abi_whitelists 86 (const vector<string>& abi_whitelist_paths); 87 88 bool 89 get_vmlinux_path_from_kernel_dist(const string& from, 90 string& vmlinux_path); 91 92 bool 93 get_binary_paths_from_kernel_dist(const string& dist_root, 94 const string& debug_info_root_path, 95 string& vmlinux_path, 96 vector<string>& module_paths); 97 98 bool 99 get_binary_paths_from_kernel_dist(const string& dist_root, 100 string& vmlinux_path, 101 vector<string>& module_paths); 102 103 string 104 get_default_system_suppression_file_path(); 105 106 string 107 get_default_user_suppression_file_path(); 108 109 void 110 load_default_system_suppressions(suppr::suppressions_type&); 111 112 void 113 load_default_user_suppressions(suppr::suppressions_type&); 114 115 bool 116 find_file_under_dir(const string& root_dir, 117 const string& file_path_to_look_for, 118 string& result); 119 120 class temp_file; 121 122 /// Convenience typedef for a shared_ptr to @ref temp_file. 123 typedef shared_ptr<temp_file> temp_file_sptr; 124 125 /// A temporary file. 126 /// 127 /// This is a helper file around the mkstemp API. 128 /// 129 /// Once the temporary file is created, users can interact with it 130 /// using an fstream. They can also get the path to the newly 131 /// created temporary file. 132 /// 133 /// When the instance of @ref temp_file is destroyed, the underlying 134 /// resources are de-allocated, the underlying temporary file is 135 /// closed and removed. 136 class temp_file 137 { 138 struct priv; 139 std::unique_ptr<priv> priv_; 140 141 temp_file(); 142 143 public: 144 145 bool 146 is_good() const; 147 148 const char* 149 get_path() const; 150 151 std::fstream& 152 get_stream(); 153 154 static temp_file_sptr 155 create(); 156 }; // end class temp_file 157 158 size_t 159 get_random_number(); 160 161 string 162 get_random_number_as_string(); 163 164 /// The different types of files understood the bi* suite of tools. 165 enum file_type 166 { 167 /// A file type we don't know about. 168 FILE_TYPE_UNKNOWN, 169 /// The native xml file format representing a translation unit. 170 FILE_TYPE_NATIVE_BI, 171 /// An elf file. Read this kind of file should yield an 172 /// abigail::corpus type. 173 FILE_TYPE_ELF, 174 /// An archive (AR) file. 175 FILE_TYPE_AR, 176 // A native abixml file format representing a corpus of one or 177 // several translation units. 178 FILE_TYPE_XML_CORPUS, 179 // A native abixml file format representing a corpus group of one or 180 // several corpora. 181 FILE_TYPE_XML_CORPUS_GROUP, 182 /// An RPM (.rpm) binary file 183 FILE_TYPE_RPM, 184 /// An SRPM (.src.rpm) file 185 FILE_TYPE_SRPM, 186 /// A DEB (.deb) binary file 187 FILE_TYPE_DEB, 188 /// A plain directory 189 FILE_TYPE_DIR, 190 /// A tar archive. The archive can be compressed with the popular 191 /// compression schemes recognized by GNU tar. 192 FILE_TYPE_TAR 193 }; 194 195 /// Exit status for abidiff and abicompat tools. 196 /// 197 /// It's actually a bit mask. The value of each enumerator is a power 198 /// of two. 199 enum abidiff_status 200 { 201 /// This is for when the compared ABIs are equal. 202 /// 203 /// Its numerical value is 0. 204 ABIDIFF_OK = 0, 205 206 /// This bit is set if there is an application error. 207 /// 208 /// Its numerical value is 1. 209 ABIDIFF_ERROR = 1, 210 211 /// This bit is set if the tool is invoked in an non appropriate 212 /// manner. 213 /// 214 /// Its numerical value is 2. 215 ABIDIFF_USAGE_ERROR = 1 << 1, 216 217 /// This bit is set if the ABIs being compared are different. 218 /// 219 /// Its numerical value is 4. 220 ABIDIFF_ABI_CHANGE = 1 << 2, 221 222 /// This bit is set if the ABIs being compared are different *and* 223 /// are incompatible. 224 /// 225 /// Its numerical value is 8. 226 ABIDIFF_ABI_INCOMPATIBLE_CHANGE = 1 << 3 227 }; 228 229 abidiff_status 230 operator|(abidiff_status, abidiff_status); 231 232 abidiff_status 233 operator&(abidiff_status, abidiff_status); 234 235 abidiff_status& 236 operator|=(abidiff_status&l, abidiff_status r); 237 238 bool 239 abidiff_status_has_error(abidiff_status s); 240 241 bool 242 abidiff_status_has_abi_change(abidiff_status s); 243 244 bool 245 abidiff_status_has_incompatible_abi_change(abidiff_status s); 246 247 /// A type used to time various part of the libabigail system. 248 class timer 249 { 250 struct priv; 251 std::unique_ptr<priv> priv_; 252 253 public: 254 enum kind 255 { 256 /// Default timer kind. 257 DEFAULT_TIMER_KIND = 0, 258 /// This kind of timer starts upon instantiation. 259 START_ON_INSTANTIATION_TIMER_KIND = 1, 260 }; 261 262 timer (kind k = DEFAULT_TIMER_KIND); 263 bool start(); 264 bool stop(); 265 time_t value_in_seconds() const; 266 bool value(time_t& hours, 267 time_t& minutes, 268 time_t& seconds, 269 time_t& milliseconds) const; 270 string value_as_string() const; 271 ~timer(); 272 }; //end class timer 273 274 ostream& operator<<(ostream&, const timer&); 275 276 ostream& 277 operator<<(ostream& output, file_type r); 278 279 file_type guess_file_type(istream& in); 280 281 file_type guess_file_type(const string& file_path); 282 283 bool 284 get_rpm_name(const string& str, string& name); 285 286 bool 287 get_rpm_arch(const string& str, string& arch); 288 289 bool 290 get_deb_name(const string& str, string& name); 291 292 bool 293 file_is_kernel_package(const string& file_path, 294 file_type file_type); 295 296 bool 297 file_is_kernel_debuginfo_package(const string& file_path, 298 file_type file_type); 299 300 std::shared_ptr<char> 301 make_path_absolute(const char*p); 302 303 char* 304 make_path_absolute_to_be_freed(const char*p); 305 306 corpus_group_sptr 307 build_corpus_group_from_kernel_dist_under(const string& root, 308 const string debug_info_root, 309 const string& vmlinux_path, 310 vector<string>& suppr_paths, 311 vector<string>& kabi_wl_paths, 312 suppr::suppressions_type& supprs, 313 bool verbose, 314 environment_sptr& env, 315 corpus::origin origin = corpus::DWARF_ORIGIN); 316 }// end namespace tools_utils 317 318 /// A macro that expands to aborting the program when executed. 319 /// 320 /// Before aborting, the macro emits informatin about the source 321 /// location where it was expanded. 322 #define ABG_ASSERT_NOT_REACHED \ 323 do { \ 324 std::cerr << "in " << __FUNCTION__ \ 325 << " at: " << __FILE__ << ":" << __LINE__ \ 326 << ": execution should not have reached this point!\n"; \ 327 abort(); \ 328 } while (false) 329 }//end namespace abigail 330 331 #endif //__ABG_TOOLS_UTILS_H 332