148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci#include "hiperf_libreport.h" 1648f512ceSopenharmony_ci 1748f512ceSopenharmony_ci#include "debug_logger.h" 1848f512ceSopenharmony_ci#include "dfx_elf.h" 1948f512ceSopenharmony_ci#include "perf_file_reader.h" 2048f512ceSopenharmony_ci#include "subcommand_dump.h" 2148f512ceSopenharmony_ci#include "subcommand_report.h" 2248f512ceSopenharmony_ci#include "utilities.h" 2348f512ceSopenharmony_ci 2448f512ceSopenharmony_ciusing namespace OHOS::Developtools::HiPerf; 2548f512ceSopenharmony_ciextern "C" { 2648f512ceSopenharmony_ci// this is a demo function 2748f512ceSopenharmony_ciconst char *EchoLoopBack(const char *echo) 2848f512ceSopenharmony_ci{ 2948f512ceSopenharmony_ci HLOGD("EchoLoopBack:%s\n", echo); 3048f512ceSopenharmony_ci return echo; 3148f512ceSopenharmony_ci} 3248f512ceSopenharmony_ci 3348f512ceSopenharmony_ciint SetDebug(bool enable) 3448f512ceSopenharmony_ci{ 3548f512ceSopenharmony_ci#ifdef HIPERF_DEBUG 3648f512ceSopenharmony_ci if (enable) { 3748f512ceSopenharmony_ci DebugLogger::GetInstance()->SetLogLevel(LEVEL_VERBOSE); 3848f512ceSopenharmony_ci DebugLogger::GetInstance()->Disable(false); 3948f512ceSopenharmony_ci } else { 4048f512ceSopenharmony_ci DebugLogger::GetInstance()->Disable(true); 4148f512ceSopenharmony_ci } 4248f512ceSopenharmony_ci#endif 4348f512ceSopenharmony_ci return 0; 4448f512ceSopenharmony_ci} 4548f512ceSopenharmony_ci 4648f512ceSopenharmony_ciint Report(const char *perfFile, const char *reportFile, const char *reportOptions) 4748f512ceSopenharmony_ci{ 4848f512ceSopenharmony_ci std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>(); 4948f512ceSopenharmony_ci HLOGD("report the file %s to %s\n", perfFile, reportFile); 5048f512ceSopenharmony_ci if (perfFile != nullptr and reportFile != nullptr) { 5148f512ceSopenharmony_ci std::vector<std::string> args; 5248f512ceSopenharmony_ci args.emplace_back("-i"); 5348f512ceSopenharmony_ci args.emplace_back(perfFile); 5448f512ceSopenharmony_ci args.emplace_back("-o"); 5548f512ceSopenharmony_ci args.emplace_back(reportFile); 5648f512ceSopenharmony_ci if (reportOptions != nullptr) { 5748f512ceSopenharmony_ci std::vector<std::string> options = StringSplit(reportOptions); 5848f512ceSopenharmony_ci for (std::string &option : options) { 5948f512ceSopenharmony_ci args.emplace_back(option); 6048f512ceSopenharmony_ci } 6148f512ceSopenharmony_ci } 6248f512ceSopenharmony_ci if (report->ParseOption(args)) { 6348f512ceSopenharmony_ci return report->OnSubCommand(args) ? 0 : -1; 6448f512ceSopenharmony_ci } 6548f512ceSopenharmony_ci } else { 6648f512ceSopenharmony_ci printf("path is nullptr\n"); 6748f512ceSopenharmony_ci } 6848f512ceSopenharmony_ci return -1; 6948f512ceSopenharmony_ci} 7048f512ceSopenharmony_ci 7148f512ceSopenharmony_ciint ReportJson(const char *perfFile, const char *reportFile) 7248f512ceSopenharmony_ci{ 7348f512ceSopenharmony_ci return ReportUnwindJson(perfFile, reportFile, nullptr); 7448f512ceSopenharmony_ci} 7548f512ceSopenharmony_ci 7648f512ceSopenharmony_ciint ReportUnwindJson(const char *perfFile, const char *reportFile, const char *symbolsDir) 7748f512ceSopenharmony_ci{ 7848f512ceSopenharmony_ci std::unique_ptr<SubCommandReport> report = std::make_unique<SubCommandReport>(); 7948f512ceSopenharmony_ci HLOGD("report the file %s to json file %s symbols from %s\n", perfFile, reportFile, symbolsDir); 8048f512ceSopenharmony_ci if (perfFile != nullptr and reportFile != nullptr) { 8148f512ceSopenharmony_ci std::vector<std::string> args; 8248f512ceSopenharmony_ci args.emplace_back("-i"); 8348f512ceSopenharmony_ci args.emplace_back(perfFile); 8448f512ceSopenharmony_ci args.emplace_back("-o"); 8548f512ceSopenharmony_ci args.emplace_back(reportFile); 8648f512ceSopenharmony_ci args.emplace_back("--json"); 8748f512ceSopenharmony_ci if (symbolsDir != nullptr) { 8848f512ceSopenharmony_ci args.emplace_back("--symbol-dir"); 8948f512ceSopenharmony_ci args.emplace_back(symbolsDir); 9048f512ceSopenharmony_ci } 9148f512ceSopenharmony_ci if (report->ParseOption(args)) { 9248f512ceSopenharmony_ci return report->OnSubCommand(args) ? 0 : -1; 9348f512ceSopenharmony_ci } 9448f512ceSopenharmony_ci } 9548f512ceSopenharmony_ci return -1; 9648f512ceSopenharmony_ci} 9748f512ceSopenharmony_ci 9848f512ceSopenharmony_cistatic std::unique_ptr<PerfFileReader> GetReader(const std::string &fileName) 9948f512ceSopenharmony_ci{ 10048f512ceSopenharmony_ci // check if file exist 10148f512ceSopenharmony_ci if (access(fileName.c_str(), F_OK) != 0) { 10248f512ceSopenharmony_ci // file not exists 10348f512ceSopenharmony_ci printf("Can not access data file %s\n", fileName.c_str()); 10448f512ceSopenharmony_ci return nullptr; 10548f512ceSopenharmony_ci } 10648f512ceSopenharmony_ci 10748f512ceSopenharmony_ci auto reader = PerfFileReader::Instance(fileName); 10848f512ceSopenharmony_ci if (reader == nullptr) { 10948f512ceSopenharmony_ci printf("%s format not correct\n", fileName.c_str()); 11048f512ceSopenharmony_ci return nullptr; 11148f512ceSopenharmony_ci } else { 11248f512ceSopenharmony_ci return reader; 11348f512ceSopenharmony_ci } 11448f512ceSopenharmony_ci} 11548f512ceSopenharmony_ci 11648f512ceSopenharmony_ciconst char *ReportGetSymbolFiles(const char *perfFile) 11748f512ceSopenharmony_ci{ 11848f512ceSopenharmony_ci HLOGD("report the file %s for symbols \n", perfFile); 11948f512ceSopenharmony_ci static std::string result; // static for hold the c_str buffer 12048f512ceSopenharmony_ci result.clear(); 12148f512ceSopenharmony_ci if (perfFile == nullptr) { 12248f512ceSopenharmony_ci return result.c_str(); 12348f512ceSopenharmony_ci } 12448f512ceSopenharmony_ci 12548f512ceSopenharmony_ci auto reader = GetReader(perfFile); 12648f512ceSopenharmony_ci if (reader == nullptr) { 12748f512ceSopenharmony_ci return result.c_str(); 12848f512ceSopenharmony_ci } 12948f512ceSopenharmony_ci // found symbols in file 13048f512ceSopenharmony_ci reader->ReadFeatureSection(); 13148f512ceSopenharmony_ci for (auto &featureSection : reader->GetFeatureSections()) { 13248f512ceSopenharmony_ci if (featureSection->featureId_ == FEATURE::HIPERF_FILES_SYMBOL) { 13348f512ceSopenharmony_ci const PerfFileSectionSymbolsFiles *sectionSymbolsFiles = 13448f512ceSopenharmony_ci static_cast<const PerfFileSectionSymbolsFiles *>(featureSection.get()); 13548f512ceSopenharmony_ci auto it = sectionSymbolsFiles->symbolFileStructs_.begin(); 13648f512ceSopenharmony_ci while (it != sectionSymbolsFiles->symbolFileStructs_.end()) { 13748f512ceSopenharmony_ci HLOGD("%s buildId:%s\n", it->filePath_.c_str(), it->buildId_.c_str()); 13848f512ceSopenharmony_ci result.append("["); 13948f512ceSopenharmony_ci result.append(it->filePath_.c_str()); 14048f512ceSopenharmony_ci result.append(","); 14148f512ceSopenharmony_ci result.append(it->buildId_.c_str()); 14248f512ceSopenharmony_ci result.append("]"); 14348f512ceSopenharmony_ci result.append(","); 14448f512ceSopenharmony_ci it++; 14548f512ceSopenharmony_ci } 14648f512ceSopenharmony_ci result[result.size() >= 1 ? result.size() - 1 : 0] = '\0'; 14748f512ceSopenharmony_ci } 14848f512ceSopenharmony_ci } 14948f512ceSopenharmony_ci return result.c_str(); 15048f512ceSopenharmony_ci} 15148f512ceSopenharmony_ci 15248f512ceSopenharmony_ciconst char *ReportGetBuildId(const char *elfPath) 15348f512ceSopenharmony_ci{ 15448f512ceSopenharmony_ci static std::string buildId; // static for hold the c_str buffer 15548f512ceSopenharmony_ci buildId.clear(); 15648f512ceSopenharmony_ci std::string path(elfPath); 15748f512ceSopenharmony_ci std::shared_ptr<DfxElf> elfFile = std::make_shared<DfxElf>(path); 15848f512ceSopenharmony_ci buildId = elfFile->GetBuildId(); 15948f512ceSopenharmony_ci return buildId.c_str(); 16048f512ceSopenharmony_ci} 16148f512ceSopenharmony_ci 16248f512ceSopenharmony_ciconst char *ReportGetElfArch(const char *elfPath) 16348f512ceSopenharmony_ci{ 16448f512ceSopenharmony_ci std::string path(elfPath); 16548f512ceSopenharmony_ci std::shared_ptr<DfxElf> elfFile = std::make_shared<DfxElf>(path); 16648f512ceSopenharmony_ci const char *machineName = "unknown"; 16748f512ceSopenharmony_ci switch (elfFile->GetArchType()) { 16848f512ceSopenharmony_ci case ArchType::ARCH_ARM: 16948f512ceSopenharmony_ci machineName = "arm"; 17048f512ceSopenharmony_ci break; 17148f512ceSopenharmony_ci case ArchType::ARCH_ARM64: 17248f512ceSopenharmony_ci machineName = "arm64"; 17348f512ceSopenharmony_ci break; 17448f512ceSopenharmony_ci case ArchType::ARCH_X86: 17548f512ceSopenharmony_ci machineName = "x86"; 17648f512ceSopenharmony_ci break; 17748f512ceSopenharmony_ci case ArchType::ARCH_X86_64: 17848f512ceSopenharmony_ci machineName = "x86_64"; 17948f512ceSopenharmony_ci break; 18048f512ceSopenharmony_ci default: 18148f512ceSopenharmony_ci break; 18248f512ceSopenharmony_ci } 18348f512ceSopenharmony_ci HLOGD("elf '%s' mache type is %s \n", elfPath, machineName); 18448f512ceSopenharmony_ci return machineName; 18548f512ceSopenharmony_ci} 18648f512ceSopenharmony_ci 18748f512ceSopenharmony_ciint Dump(const char *fileName) 18848f512ceSopenharmony_ci{ 18948f512ceSopenharmony_ci std::unique_ptr<SubCommandDump> dump = std::make_unique<SubCommandDump>(); 19048f512ceSopenharmony_ci HLOGD("dump the file %s\n", fileName); 19148f512ceSopenharmony_ci if (fileName != nullptr) { 19248f512ceSopenharmony_ci std::vector<std::string> args; 19348f512ceSopenharmony_ci args.emplace_back(fileName); 19448f512ceSopenharmony_ci if (dump->ParseOption(args)) { 19548f512ceSopenharmony_ci return dump->OnSubCommand(args) ? 0 : -1; 19648f512ceSopenharmony_ci } 19748f512ceSopenharmony_ci } 19848f512ceSopenharmony_ci return -1; 19948f512ceSopenharmony_ci} 20048f512ceSopenharmony_ci 20148f512ceSopenharmony_ci} // extern "C" 202