167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui/* 267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Copyright (C) 2015 The Android Open Source Project 367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Licensed under the Apache License, Version 2.0 (the "License"); 567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * you may not use this file except in compliance with the License. 667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * You may obtain a copy of the License at 767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * http://www.apache.org/licenses/LICENSE-2.0 967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * 1067d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * Unless required by applicable law or agreed to in writing, software 1167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * distributed under the License is distributed on an "AS IS" BASIS, 1267d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * See the License for the specific language governing permissions and 1467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui * limitations under the License. 1567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui */ 1667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 1767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include "utils.h" 1867d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 197d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui#include <dirent.h> 20323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui#include <errno.h> 21b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui#include <fcntl.h> 22b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui#include <inttypes.h> 2367d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <stdarg.h> 2467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui#include <stdio.h> 256afc7e17d39ab294bdf625076777443a6b4c8e18Yabin Cui#include <sys/stat.h> 26323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui#include <unistd.h> 27323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui 28cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui#include <algorithm> 298f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui#include <map> 30cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui#include <string> 31cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui 32b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui#include <android-base/file.h> 3366dd09e8e2407082ce93bf0784de641298131912Elliott Hughes#include <android-base/logging.h> 3467d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui 3505400539d15c50a52a388daba2e831b86824cc8eYabin Cui#include <7zCrc.h> 3605400539d15c50a52a388daba2e831b86824cc8eYabin Cui#include <Xz.h> 3705400539d15c50a52a388daba2e831b86824cc8eYabin Cui#include <XzCrc64.h> 3805400539d15c50a52a388daba2e831b86824cc8eYabin Cui 39cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cuivoid OneTimeFreeAllocator::Clear() { 40cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui for (auto& p : v_) { 41cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui delete[] p; 42cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui } 43cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui v_.clear(); 44cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui cur_ = nullptr; 45cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui end_ = nullptr; 46cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui} 47cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui 48cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cuiconst char* OneTimeFreeAllocator::AllocateString(const std::string& s) { 49cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui size_t size = s.size() + 1; 50cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui if (cur_ + size > end_) { 51cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui size_t alloc_size = std::max(size, unit_size_); 52cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui char* p = new char[alloc_size]; 53cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui v_.push_back(p); 54cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui cur_ = p; 55cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui end_ = p + alloc_size; 56cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui } 57cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui strcpy(cur_, s.c_str()); 58cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui const char* result = cur_; 59cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui cur_ += size; 60cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui return result; 61cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui} 62cc2e59e2478d330c89eaceda0dcc1f05ee32fbf8Yabin Cui 63be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui 64be7ec66eaa4f995bd9068637f7c7d5718173922cYabin CuiFileHelper FileHelper::OpenReadOnly(const std::string& filename) { 65be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY | O_BINARY)); 66be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui return FileHelper(fd); 67b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui} 68b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 69be7ec66eaa4f995bd9068637f7c7d5718173922cYabin CuiFileHelper FileHelper::OpenWriteOnly(const std::string& filename) { 70be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_WRONLY | O_BINARY | O_CREAT, 0644)); 71be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui return FileHelper(fd); 72b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui} 73b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 74b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin CuiFileHelper::~FileHelper() { 75b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui if (fd_ != -1) { 76b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui close(fd_); 77b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui } 78b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui} 79b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 80be7ec66eaa4f995bd9068637f7c7d5718173922cYabin CuiArchiveHelper::ArchiveHelper(int fd, const std::string& debug_filename) : valid_(false) { 81be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui int rc = OpenArchiveFd(fd, "", &handle_, false); 82be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui if (rc == 0) { 83be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui valid_ = true; 84be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } else { 85be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui LOG(ERROR) << "Failed to open archive " << debug_filename << ": " << ErrorCodeString(rc); 86be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } 87be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui} 88be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui 89be7ec66eaa4f995bd9068637f7c7d5718173922cYabin CuiArchiveHelper::~ArchiveHelper() { 90be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui if (valid_) { 91be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui CloseArchive(handle_); 92be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } 93be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui} 94be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui 9567d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cuivoid PrintIndented(size_t indent, const char* fmt, ...) { 9667d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui va_list ap; 9767d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui va_start(ap, fmt); 989759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui printf("%*s", static_cast<int>(indent * 2), ""); 9967d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui vprintf(fmt, ap); 10067d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui va_end(ap); 10167d3abd7b26a741347b33402ad32f5c6735ca0bdYabin Cui} 102323e945313b190373b3fcfe578e25ee8390a76d3Yabin Cui 103767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cuivoid FprintIndented(FILE* fp, size_t indent, const char* fmt, ...) { 104767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui va_list ap; 105767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui va_start(ap, fmt); 106767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui fprintf(fp, "%*s", static_cast<int>(indent * 2), ""); 107767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui vfprintf(fp, fmt, ap); 108767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui va_end(ap); 109767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui} 110767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui 1119759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cuibool IsPowerOfTwo(uint64_t value) { 1129759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui return (value != 0 && ((value & (value - 1)) == 0)); 1139759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui} 1149759e1b1ce76185aa539aeea2fb1cbd8382156e7Yabin Cui 115078658638c01c035ebcb98a557628101566a1d57Yabin Cuistd::vector<std::string> GetEntriesInDir(const std::string& dirpath) { 116078658638c01c035ebcb98a557628101566a1d57Yabin Cui std::vector<std::string> result; 1177d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui DIR* dir = opendir(dirpath.c_str()); 1187d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui if (dir == nullptr) { 1197d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui PLOG(DEBUG) << "can't open dir " << dirpath; 120078658638c01c035ebcb98a557628101566a1d57Yabin Cui return result; 1217d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui } 1227d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui dirent* entry; 1237d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui while ((entry = readdir(dir)) != nullptr) { 1247d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { 1257d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui continue; 1267d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui } 127078658638c01c035ebcb98a557628101566a1d57Yabin Cui result.push_back(entry->d_name); 1287d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui } 1297d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui closedir(dir); 130078658638c01c035ebcb98a557628101566a1d57Yabin Cui return result; 131078658638c01c035ebcb98a557628101566a1d57Yabin Cui} 132078658638c01c035ebcb98a557628101566a1d57Yabin Cui 133078658638c01c035ebcb98a557628101566a1d57Yabin Cuistd::vector<std::string> GetSubDirs(const std::string& dirpath) { 134078658638c01c035ebcb98a557628101566a1d57Yabin Cui std::vector<std::string> entries = GetEntriesInDir(dirpath); 135078658638c01c035ebcb98a557628101566a1d57Yabin Cui std::vector<std::string> result; 136078658638c01c035ebcb98a557628101566a1d57Yabin Cui for (size_t i = 0; i < entries.size(); ++i) { 137078658638c01c035ebcb98a557628101566a1d57Yabin Cui if (IsDir(dirpath + "/" + entries[i])) { 138078658638c01c035ebcb98a557628101566a1d57Yabin Cui result.push_back(std::move(entries[i])); 139078658638c01c035ebcb98a557628101566a1d57Yabin Cui } 140078658638c01c035ebcb98a557628101566a1d57Yabin Cui } 141078658638c01c035ebcb98a557628101566a1d57Yabin Cui return result; 1427d59bb49fb47fbc82ef5c77d7aebf7174fd996e1Yabin Cui} 1436afc7e17d39ab294bdf625076777443a6b4c8e18Yabin Cui 144b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cuibool IsDir(const std::string& dirpath) { 145b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui struct stat st; 146b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui if (stat(dirpath.c_str(), &st) == 0) { 147b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui if (S_ISDIR(st.st_mode)) { 148b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui return true; 149b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui } 150b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui } 151b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui return false; 152b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui} 153b032de7a9e1975a838cd6df2e7c8df3c7f70a3ceYabin Cui 154797116bfb9ad10d858086680c7465d65c399ef6eYabin Cuibool IsRegularFile(const std::string& filename) { 155797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui struct stat st; 156797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui if (stat(filename.c_str(), &st) == 0) { 157797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui if (S_ISREG(st.st_mode)) { 158797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui return true; 159797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui } 160797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui } 161797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui return false; 162797116bfb9ad10d858086680c7465d65c399ef6eYabin Cui} 163b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui 164b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cuiuint64_t GetFileSize(const std::string& filename) { 165b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui struct stat st; 166b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui if (stat(filename.c_str(), &st) == 0) { 167b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui return static_cast<uint64_t>(st.st_size); 168b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui } 169b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui return 0; 170b1a885b014540a2f7798b5a35ea0f0ec150d93eeYabin Cui} 171be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui 172be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cuibool MkdirWithParents(const std::string& path) { 173be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui size_t prev_end = 0; 174be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui while (prev_end < path.size()) { 175be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui size_t next_end = path.find('/', prev_end + 1); 176be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui if (next_end == std::string::npos) { 177be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui break; 178be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } 179be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui std::string dir_path = path.substr(0, next_end); 180be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui if (!IsDir(dir_path)) { 181be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#if defined(_WIN32) 182be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui int ret = mkdir(dir_path.c_str()); 183be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#else 184be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui int ret = mkdir(dir_path.c_str(), 0755); 185be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui#endif 186be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui if (ret != 0) { 187be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui PLOG(ERROR) << "failed to create dir " << dir_path; 188be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui return false; 189be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } 190be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } 191be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui prev_end = next_end; 192be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui } 193be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui return true; 194be7ec66eaa4f995bd9068637f7c7d5718173922cYabin Cui} 19505400539d15c50a52a388daba2e831b86824cc8eYabin Cui 19605400539d15c50a52a388daba2e831b86824cc8eYabin Cuistatic void* xz_alloc(void*, size_t size) { 19705400539d15c50a52a388daba2e831b86824cc8eYabin Cui return malloc(size); 19805400539d15c50a52a388daba2e831b86824cc8eYabin Cui} 19905400539d15c50a52a388daba2e831b86824cc8eYabin Cui 20005400539d15c50a52a388daba2e831b86824cc8eYabin Cuistatic void xz_free(void*, void* address) { 20105400539d15c50a52a388daba2e831b86824cc8eYabin Cui free(address); 20205400539d15c50a52a388daba2e831b86824cc8eYabin Cui} 20305400539d15c50a52a388daba2e831b86824cc8eYabin Cui 20405400539d15c50a52a388daba2e831b86824cc8eYabin Cuibool XzDecompress(const std::string& compressed_data, std::string* decompressed_data) { 20505400539d15c50a52a388daba2e831b86824cc8eYabin Cui ISzAlloc alloc; 20605400539d15c50a52a388daba2e831b86824cc8eYabin Cui CXzUnpacker state; 20705400539d15c50a52a388daba2e831b86824cc8eYabin Cui alloc.Alloc = xz_alloc; 20805400539d15c50a52a388daba2e831b86824cc8eYabin Cui alloc.Free = xz_free; 20905400539d15c50a52a388daba2e831b86824cc8eYabin Cui XzUnpacker_Construct(&state, &alloc); 21005400539d15c50a52a388daba2e831b86824cc8eYabin Cui CrcGenerateTable(); 21105400539d15c50a52a388daba2e831b86824cc8eYabin Cui Crc64GenerateTable(); 21205400539d15c50a52a388daba2e831b86824cc8eYabin Cui size_t src_offset = 0; 21305400539d15c50a52a388daba2e831b86824cc8eYabin Cui size_t dst_offset = 0; 21405400539d15c50a52a388daba2e831b86824cc8eYabin Cui std::string dst(compressed_data.size(), ' '); 21505400539d15c50a52a388daba2e831b86824cc8eYabin Cui 21605400539d15c50a52a388daba2e831b86824cc8eYabin Cui ECoderStatus status = CODER_STATUS_NOT_FINISHED; 21705400539d15c50a52a388daba2e831b86824cc8eYabin Cui while (status == CODER_STATUS_NOT_FINISHED) { 21805400539d15c50a52a388daba2e831b86824cc8eYabin Cui dst.resize(dst.size() * 2); 21905400539d15c50a52a388daba2e831b86824cc8eYabin Cui size_t src_remaining = compressed_data.size() - src_offset; 22005400539d15c50a52a388daba2e831b86824cc8eYabin Cui size_t dst_remaining = dst.size() - dst_offset; 22105400539d15c50a52a388daba2e831b86824cc8eYabin Cui int res = XzUnpacker_Code(&state, reinterpret_cast<Byte*>(&dst[dst_offset]), &dst_remaining, 22205400539d15c50a52a388daba2e831b86824cc8eYabin Cui reinterpret_cast<const Byte*>(&compressed_data[src_offset]), 22305400539d15c50a52a388daba2e831b86824cc8eYabin Cui &src_remaining, CODER_FINISH_ANY, &status); 22405400539d15c50a52a388daba2e831b86824cc8eYabin Cui if (res != SZ_OK) { 22505400539d15c50a52a388daba2e831b86824cc8eYabin Cui LOG(ERROR) << "LZMA decompression failed with error " << res; 22605400539d15c50a52a388daba2e831b86824cc8eYabin Cui XzUnpacker_Free(&state); 22705400539d15c50a52a388daba2e831b86824cc8eYabin Cui return false; 22805400539d15c50a52a388daba2e831b86824cc8eYabin Cui } 22905400539d15c50a52a388daba2e831b86824cc8eYabin Cui src_offset += src_remaining; 23005400539d15c50a52a388daba2e831b86824cc8eYabin Cui dst_offset += dst_remaining; 23105400539d15c50a52a388daba2e831b86824cc8eYabin Cui } 23205400539d15c50a52a388daba2e831b86824cc8eYabin Cui XzUnpacker_Free(&state); 23305400539d15c50a52a388daba2e831b86824cc8eYabin Cui if (!XzUnpacker_IsStreamWasFinished(&state)) { 23405400539d15c50a52a388daba2e831b86824cc8eYabin Cui LOG(ERROR) << "LZMA decompresstion failed due to incomplete stream"; 23505400539d15c50a52a388daba2e831b86824cc8eYabin Cui return false; 23605400539d15c50a52a388daba2e831b86824cc8eYabin Cui } 23705400539d15c50a52a388daba2e831b86824cc8eYabin Cui dst.resize(dst_offset); 23805400539d15c50a52a388daba2e831b86824cc8eYabin Cui *decompressed_data = std::move(dst); 23905400539d15c50a52a388daba2e831b86824cc8eYabin Cui return true; 24005400539d15c50a52a388daba2e831b86824cc8eYabin Cui} 2418f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui 2428f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cuibool GetLogSeverity(const std::string& name, android::base::LogSeverity* severity) { 2438f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui static std::map<std::string, android::base::LogSeverity> log_severity_map = { 2448f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui {"verbose", android::base::VERBOSE}, 2458f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui {"debug", android::base::DEBUG}, 246767dd17947f1ae9dd3d02f738d442a23ed76f2f6Yabin Cui {"info", android::base::INFO}, 2478f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui {"warning", android::base::WARNING}, 2488f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui {"error", android::base::ERROR}, 2498f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui {"fatal", android::base::FATAL}, 2508f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui }; 2518f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui auto it = log_severity_map.find(name); 2528f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui if (it != log_severity_map.end()) { 2538f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui *severity = it->second; 2548f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui return true; 2558f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui } 2568f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui return false; 2578f680f60dc800bec880c5c35bfbc1ac36165e1f3Yabin Cui} 2585633586f0efc54dbaecad3deeb8568786317832dYabin Cui 2595633586f0efc54dbaecad3deeb8568786317832dYabin Cuibool IsRoot() { 2605633586f0efc54dbaecad3deeb8568786317832dYabin Cui static int is_root = -1; 2615633586f0efc54dbaecad3deeb8568786317832dYabin Cui if (is_root == -1) { 2625633586f0efc54dbaecad3deeb8568786317832dYabin Cui#if defined(__linux__) 2635633586f0efc54dbaecad3deeb8568786317832dYabin Cui is_root = (getuid() == 0) ? 1 : 0; 2645633586f0efc54dbaecad3deeb8568786317832dYabin Cui#else 2655633586f0efc54dbaecad3deeb8568786317832dYabin Cui is_root = 0; 2665633586f0efc54dbaecad3deeb8568786317832dYabin Cui#endif 2675633586f0efc54dbaecad3deeb8568786317832dYabin Cui } 2685633586f0efc54dbaecad3deeb8568786317832dYabin Cui return is_root == 1; 2695633586f0efc54dbaecad3deeb8568786317832dYabin Cui} 270b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui 271b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cuibool ProcessKernelSymbols(std::string& symbol_data, 2723e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui const std::function<bool(const KernelSymbol&)>& callback) { 273b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui char* p = &symbol_data[0]; 274b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui char* data_end = p + symbol_data.size(); 275b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui while (p < data_end) { 276b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui char* line_end = strchr(p, '\n'); 277b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui if (line_end != nullptr) { 278b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui *line_end = '\0'; 279b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } 280b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui size_t line_size = (line_end != nullptr) ? (line_end - p) : (data_end - p); 281b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui // Parse line like: ffffffffa005c4e4 d __warned.41698 [libsas] 282b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui char name[line_size]; 283b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui char module[line_size]; 284b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui strcpy(module, ""); 285b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui 286b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui KernelSymbol symbol; 287b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui int ret = sscanf(p, "%" PRIx64 " %c %s%s", &symbol.addr, &symbol.type, name, module); 288b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui if (line_end != nullptr) { 289b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui *line_end = '\n'; 290b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui p = line_end + 1; 291b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } else { 292b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui p = data_end; 293b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } 294b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui if (ret >= 3) { 295b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui symbol.name = name; 296b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui size_t module_len = strlen(module); 297b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui if (module_len > 2 && module[0] == '[' && module[module_len - 1] == ']') { 298b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui module[module_len - 1] = '\0'; 299b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui symbol.module = &module[1]; 300b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } else { 301b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui symbol.module = nullptr; 302b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } 303b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui 304b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui if (callback(symbol)) { 305b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui return true; 306b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } 307b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } 308b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui } 309b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui return false; 310b42129797f17f990ea5a88c6bdc7446000cc361cYabin Cui} 3114f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui 3124f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cuisize_t GetPageSize() { 3134f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui#if defined(__linux__) 3144f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui return sysconf(_SC_PAGE_SIZE); 3154f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui#else 3164f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui return 4096; 3174f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui#endif 3184f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui} 3194f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui 3204f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cuiuint64_t ConvertBytesToValue(const char* bytes, uint32_t size) { 321f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui if (size > 8) { 322f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui LOG(FATAL) << "unexpected size " << size << " in ConvertBytesToValue"; 3234f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui } 324f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui uint64_t result = 0; 325f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui int shift = 0; 326f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui for (uint32_t i = 0; i < size; ++i) { 327f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui uint64_t tmp = static_cast<unsigned char>(bytes[i]); 328f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui result |= tmp << shift; 329f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui shift += 8; 330f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui } 331f79a00874d415ba7e7fda01cf2eb76bf06e459a6Yabin Cui return result; 3324f41df6f68efc3b9b534014a8cfb6ee8ac4d5c91Yabin Cui} 3333e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui 3343e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cuitimeval SecondToTimeval(double time_in_sec) { 3353e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui timeval tv; 3363e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui tv.tv_sec = static_cast<time_t>(time_in_sec); 3373e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui tv.tv_usec = static_cast<int>((time_in_sec - tv.tv_sec) * 1000000); 3383e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui return tv; 3393e4c5950f3aafb0bf66544468d98ee3ec26b705cYabin Cui} 340