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 <string.h> 21 #include <algorithm> 22 #include <android-base/stringprintf.h> 23 24 constexpr size_t BUILD_ID_SIZE = 20; 25 26 // Shared libraries can have a section called .note.gnu.build-id, containing 27 // a ~20 bytes unique id. Build id is used to compare if two shared libraries 28 // are actually the same. BuildId class is the representation of build id in 29 // memory. 30 class BuildId { 31 public: Size()32 static size_t Size() { 33 return BUILD_ID_SIZE; 34 } 35 BuildId()36 BuildId() { 37 memset(data_, '\0', BUILD_ID_SIZE); 38 } 39 40 // Copy build id from a byte array, like {0x76, 0x00, 0x32,...}. BuildId(const void * data,size_t len)41 BuildId(const void* data, size_t len) : BuildId() { 42 memcpy(data_, data, std::min(len, BUILD_ID_SIZE)); 43 } 44 45 // Read build id from a hex string, like "7600329e31058e12b145d153ef27cd40e1a5f7b9". BuildId(const std::string & s)46 explicit BuildId(const std::string& s) : BuildId() { 47 for (size_t i = 0; i < s.size() && i < BUILD_ID_SIZE * 2; i += 2) { 48 unsigned char ch = 0; 49 for (size_t j = i; j < i + 2; ++j) { 50 ch <<= 4; 51 if (s[j] >= '0' && s[j] <= '9') { 52 ch |= s[j] - '0'; 53 } else if (s[j] >= 'a' && s[j] <= 'f') { 54 ch |= s[j] - 'a' + 10; 55 } else if (s[j] >= 'A' && s[j] <= 'F') { 56 ch |= s[j] - 'A' + 10; 57 } 58 } 59 data_[i / 2] = ch; 60 } 61 } 62 Data()63 const unsigned char* Data() const { 64 return data_; 65 } 66 ToString()67 std::string ToString() const { 68 std::string s = "0x"; 69 for (size_t i = 0; i < BUILD_ID_SIZE; ++i) { 70 s += android::base::StringPrintf("%02x", data_[i]); 71 } 72 return s; 73 } 74 75 bool operator==(const BuildId& build_id) const { 76 return memcmp(data_, build_id.data_, BUILD_ID_SIZE) == 0; 77 } 78 79 bool operator!=(const BuildId& build_id) const { 80 return !(*this == build_id); 81 } 82 IsEmpty()83 bool IsEmpty() const { 84 static BuildId empty_build_id; 85 return *this == empty_build_id; 86 } 87 88 private: 89 unsigned char data_[BUILD_ID_SIZE]; 90 }; 91 92 inline std::ostream& operator<<(std::ostream& os, const BuildId& build_id) { 93 os << build_id.ToString(); 94 return os; 95 } 96 97 #endif // SIMPLE_PERF_BUILD_ID_H_ 98