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