1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SIMPLE_PERF_BUILD_ID_H_ 18 #define SIMPLE_PERF_BUILD_ID_H_ 19 20 #include <android-base/stringprintf.h> 21 #include <string.h> 22 #include <algorithm> 23 24 namespace simpleperf { 25 26 constexpr size_t BUILD_ID_SIZE = 20; 27 28 // Shared libraries can have a section called .note.gnu.build-id, containing 29 // a ~20 bytes unique id. Build id is used to compare if two shared libraries 30 // are actually the same. BuildId class is the representation of build id in 31 // memory. 32 class BuildId { 33 public: Size()34 static size_t Size() { return BUILD_ID_SIZE; } 35 BuildId()36 BuildId() { memset(data_, '\0', BUILD_ID_SIZE); } 37 38 // Copy build id from a byte array, like {0x76, 0x00, 0x32,...}. BuildId(const void * data,size_t len)39 BuildId(const void* data, size_t len) : BuildId() { 40 memcpy(data_, data, std::min(len, BUILD_ID_SIZE)); 41 } 42 43 // Read build id from a hex string, like "7600329e31058e12b145d153ef27cd40e1a5f7b9". BuildId(const std::string & s)44 explicit BuildId(const std::string& s) : BuildId() { 45 for (size_t i = 0; i < s.size() && i < BUILD_ID_SIZE * 2; i += 2) { 46 unsigned char ch = 0; 47 for (size_t j = i; j < i + 2; ++j) { 48 ch <<= 4; 49 if (s[j] >= '0' && s[j] <= '9') { 50 ch |= s[j] - '0'; 51 } else if (s[j] >= 'a' && s[j] <= 'f') { 52 ch |= s[j] - 'a' + 10; 53 } else if (s[j] >= 'A' && s[j] <= 'F') { 54 ch |= s[j] - 'A' + 10; 55 } 56 } 57 data_[i / 2] = ch; 58 } 59 } 60 Data()61 const unsigned char* Data() const { return data_; } 62 ToString()63 std::string ToString() const { 64 std::string s = "0x"; 65 for (size_t i = 0; i < BUILD_ID_SIZE; ++i) { 66 s += android::base::StringPrintf("%02x", data_[i]); 67 } 68 return s; 69 } 70 71 bool operator==(const BuildId& build_id) const { 72 return memcmp(data_, build_id.data_, BUILD_ID_SIZE) == 0; 73 } 74 75 bool operator!=(const BuildId& build_id) const { return !(*this == build_id); } 76 IsEmpty()77 bool IsEmpty() const { 78 static BuildId empty_build_id; 79 return *this == empty_build_id; 80 } 81 82 private: 83 unsigned char data_[BUILD_ID_SIZE]; 84 }; 85 86 inline std::ostream& operator<<(std::ostream& os, const BuildId& build_id) { 87 os << build_id.ToString(); 88 return os; 89 } 90 91 } // namespace simpleperf 92 93 #endif // SIMPLE_PERF_BUILD_ID_H_ 94