1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "elf_imitate.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <cstdlib> 19800b99b8Sopenharmony_ci#include <securec.h> 20800b99b8Sopenharmony_ci#include <string> 21800b99b8Sopenharmony_ci#include <sys/mman.h> 22800b99b8Sopenharmony_ci#include <sys/types.h> 23800b99b8Sopenharmony_ci#include <unistd.h> 24800b99b8Sopenharmony_ci#include <utility> 25800b99b8Sopenharmony_ci#include "dfx_define.h" 26800b99b8Sopenharmony_ci#include "dfx_log.h" 27800b99b8Sopenharmony_ci#include "dfx_util.h" 28800b99b8Sopenharmony_ci#include <iostream> 29800b99b8Sopenharmony_ci 30800b99b8Sopenharmony_ci#ifndef PAGE_SIZE 31800b99b8Sopenharmony_ci#define PAGE_SIZE 4096 32800b99b8Sopenharmony_ci#endif 33800b99b8Sopenharmony_ci 34800b99b8Sopenharmony_cinamespace { 35800b99b8Sopenharmony_ciconst std::string EHDR_32 {"/data/test/resource/testdata/ehdr_from_readelf_32"}; 36800b99b8Sopenharmony_ciconst std::string EHDR_64 {"/data/test/resource/testdata/ehdr_from_readelf_64"}; 37800b99b8Sopenharmony_ciconst std::string SHDRS_32 {"/data/test/resource/testdata/shdrs_from_readelf_32"}; 38800b99b8Sopenharmony_ciconst std::string SHDRS_64 {"/data/test/resource/testdata/shdrs_from_readelf_64"}; 39800b99b8Sopenharmony_ciconst std::string PHDRS_32 {"/data/test/resource/testdata/phdrs_from_readelf_32"}; 40800b99b8Sopenharmony_ciconst std::string PHDRS_64 {"/data/test/resource/testdata/phdrs_from_readelf_64"}; 41800b99b8Sopenharmony_ciconst std::string SYMS_32 {"/data/test/resource/testdata/syms_from_readelf_32"}; 42800b99b8Sopenharmony_ciconst std::string SYMS_64 {"/data/test/resource/testdata/syms_from_readelf_64"}; 43800b99b8Sopenharmony_ci} // namespace 44800b99b8Sopenharmony_cinamespace OHOS { 45800b99b8Sopenharmony_cinamespace HiviewDFX { 46800b99b8Sopenharmony_ciElfImitate::~ElfImitate() 47800b99b8Sopenharmony_ci{ 48800b99b8Sopenharmony_ci if (ehdrFP_ != nullptr) { 49800b99b8Sopenharmony_ci fclose(ehdrFP_); 50800b99b8Sopenharmony_ci ehdrFP_ = nullptr; 51800b99b8Sopenharmony_ci } 52800b99b8Sopenharmony_ci if (shdrFP_ != nullptr) { 53800b99b8Sopenharmony_ci fclose(shdrFP_); 54800b99b8Sopenharmony_ci shdrFP_ = nullptr; 55800b99b8Sopenharmony_ci } 56800b99b8Sopenharmony_ci if (phdrFP_ != nullptr) { 57800b99b8Sopenharmony_ci fclose(phdrFP_); 58800b99b8Sopenharmony_ci phdrFP_ = nullptr; 59800b99b8Sopenharmony_ci } 60800b99b8Sopenharmony_ci if (symTabFP_ != nullptr) { 61800b99b8Sopenharmony_ci fclose(symTabFP_); 62800b99b8Sopenharmony_ci symTabFP_ = nullptr; 63800b99b8Sopenharmony_ci } 64800b99b8Sopenharmony_ci} 65800b99b8Sopenharmony_ci 66800b99b8Sopenharmony_cistatic const std::string GetNextLine(FILE *fp, int *status) 67800b99b8Sopenharmony_ci{ 68800b99b8Sopenharmony_ci constexpr int bufSize {128}; 69800b99b8Sopenharmony_ci char buf[bufSize] = {0}; 70800b99b8Sopenharmony_ci if (fgets(buf, bufSize, fp) == nullptr) { 71800b99b8Sopenharmony_ci DFXLOGE("fgets() failed"); 72800b99b8Sopenharmony_ci *status = -1; 73800b99b8Sopenharmony_ci return ""; 74800b99b8Sopenharmony_ci } 75800b99b8Sopenharmony_ci *status = 0; 76800b99b8Sopenharmony_ci std::string res {buf}; 77800b99b8Sopenharmony_ci if (res.back() == '\n') { 78800b99b8Sopenharmony_ci res.pop_back(); 79800b99b8Sopenharmony_ci } 80800b99b8Sopenharmony_ci return res; 81800b99b8Sopenharmony_ci} 82800b99b8Sopenharmony_cistd::vector<std::string> ElfImitate::StringSplit(std::string src, const std::string split) 83800b99b8Sopenharmony_ci{ 84800b99b8Sopenharmony_ci std::vector<std::string> result; 85800b99b8Sopenharmony_ci 86800b99b8Sopenharmony_ci if (!split.empty()) { 87800b99b8Sopenharmony_ci size_t pos = 0; 88800b99b8Sopenharmony_ci while ((pos = src.find(split)) != std::string::npos) { 89800b99b8Sopenharmony_ci // split 90800b99b8Sopenharmony_ci std::string token = src.substr(0, pos); 91800b99b8Sopenharmony_ci if (!token.empty()) { 92800b99b8Sopenharmony_ci result.push_back(token); 93800b99b8Sopenharmony_ci } 94800b99b8Sopenharmony_ci src.erase(0, pos + split.length()); 95800b99b8Sopenharmony_ci } 96800b99b8Sopenharmony_ci } 97800b99b8Sopenharmony_ci 98800b99b8Sopenharmony_ci if (!src.empty()) { 99800b99b8Sopenharmony_ci result.push_back(src); 100800b99b8Sopenharmony_ci } 101800b99b8Sopenharmony_ci return result; 102800b99b8Sopenharmony_ci} 103800b99b8Sopenharmony_ci 104800b99b8Sopenharmony_cibool ElfImitate::ParseAllHeaders(ElfFileType fileType) 105800b99b8Sopenharmony_ci{ 106800b99b8Sopenharmony_ci if (fileType == ElfFileType::ELF32) { 107800b99b8Sopenharmony_ci ehdrFP_ = std::fopen(EHDR_32.c_str(), "rb"); 108800b99b8Sopenharmony_ci if (ehdrFP_ == nullptr) { 109800b99b8Sopenharmony_ci DFXLOGE("fopen(EHDR_32, \"r\") failed"); 110800b99b8Sopenharmony_ci } 111800b99b8Sopenharmony_ci shdrFP_ = fopen(SHDRS_32.c_str(), "rb"); 112800b99b8Sopenharmony_ci if (shdrFP_ == nullptr) { 113800b99b8Sopenharmony_ci DFXLOGE("fopen(SHDRS_32, \"r\") failed"); 114800b99b8Sopenharmony_ci } 115800b99b8Sopenharmony_ci phdrFP_ = fopen(PHDRS_32.c_str(), "rb"); 116800b99b8Sopenharmony_ci if (phdrFP_ == nullptr) { 117800b99b8Sopenharmony_ci DFXLOGE("fopen(PHDRS_32, \"r\") failed"); 118800b99b8Sopenharmony_ci } 119800b99b8Sopenharmony_ci symTabFP_ = fopen(SYMS_32.c_str(), "rb"); 120800b99b8Sopenharmony_ci if (symTabFP_ == nullptr) { 121800b99b8Sopenharmony_ci DFXLOGE("fopen(SYMS_32, \"r\") failed"); 122800b99b8Sopenharmony_ci } 123800b99b8Sopenharmony_ci } else if (fileType == ElfFileType::ELF64) { 124800b99b8Sopenharmony_ci ehdrFP_ = fopen(EHDR_64.c_str(), "rb"); 125800b99b8Sopenharmony_ci if (ehdrFP_ == nullptr) { 126800b99b8Sopenharmony_ci DFXLOGE("fopen(EHDR_64, \"r\") failed"); 127800b99b8Sopenharmony_ci } 128800b99b8Sopenharmony_ci shdrFP_ = fopen(SHDRS_64.c_str(), "rb"); 129800b99b8Sopenharmony_ci if (shdrFP_ == nullptr) { 130800b99b8Sopenharmony_ci DFXLOGE("fopen(SHDRS_64, \"r\") failed"); 131800b99b8Sopenharmony_ci } 132800b99b8Sopenharmony_ci phdrFP_ = fopen(PHDRS_64.c_str(), "rb"); 133800b99b8Sopenharmony_ci if (phdrFP_ == nullptr) { 134800b99b8Sopenharmony_ci DFXLOGE("fopen(PHDRS_64, \"r\") failed"); 135800b99b8Sopenharmony_ci } 136800b99b8Sopenharmony_ci symTabFP_ = fopen(SYMS_64.c_str(), "rb"); 137800b99b8Sopenharmony_ci if (symTabFP_ == nullptr) { 138800b99b8Sopenharmony_ci DFXLOGE("fopen(SYMS_64, \"r\") failed"); 139800b99b8Sopenharmony_ci } 140800b99b8Sopenharmony_ci } 141800b99b8Sopenharmony_ci if (!ParseElfHeaders()) { 142800b99b8Sopenharmony_ci DFXLOGW("ParseElfHeaders failed"); 143800b99b8Sopenharmony_ci return false; 144800b99b8Sopenharmony_ci } 145800b99b8Sopenharmony_ci 146800b99b8Sopenharmony_ci if (!ParseProgramHeaders(fileType)) { 147800b99b8Sopenharmony_ci DFXLOGW("ParseProgramHeaders failed"); 148800b99b8Sopenharmony_ci return false; 149800b99b8Sopenharmony_ci } 150800b99b8Sopenharmony_ci 151800b99b8Sopenharmony_ci if (!ParseSectionHeaders(fileType)) { 152800b99b8Sopenharmony_ci DFXLOGW("ReadSectionHeaders failed"); 153800b99b8Sopenharmony_ci return false; 154800b99b8Sopenharmony_ci } 155800b99b8Sopenharmony_ci if (!ParseElfSymbols()) { 156800b99b8Sopenharmony_ci DFXLOGW("ParseElfSymbols failed"); 157800b99b8Sopenharmony_ci return false; 158800b99b8Sopenharmony_ci } 159800b99b8Sopenharmony_ci return true; 160800b99b8Sopenharmony_ci} 161800b99b8Sopenharmony_ci 162800b99b8Sopenharmony_cibool ElfImitate::ParseElfHeaders() 163800b99b8Sopenharmony_ci{ 164800b99b8Sopenharmony_ci if (ehdrFP_ == nullptr) { 165800b99b8Sopenharmony_ci DFXLOGE("param is null"); 166800b99b8Sopenharmony_ci return false; 167800b99b8Sopenharmony_ci } 168800b99b8Sopenharmony_ci int status {0}; 169800b99b8Sopenharmony_ci // drop header line 170800b99b8Sopenharmony_ci GetNextLine(ehdrFP_, &status); 171800b99b8Sopenharmony_ci if (!GetMagic(ehdrFP_)) { 172800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitMagic(ehdrFP_) failed:"); 173800b99b8Sopenharmony_ci return false; 174800b99b8Sopenharmony_ci } 175800b99b8Sopenharmony_ci if (!GetClass(ehdrFP_)) { 176800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitClass(ehdrFP_) failed:"); 177800b99b8Sopenharmony_ci return false; 178800b99b8Sopenharmony_ci } 179800b99b8Sopenharmony_ci constexpr int numSkip {6}; 180800b99b8Sopenharmony_ci // drop unused 6 lines 181800b99b8Sopenharmony_ci for (int count = 0; count < numSkip; ++count) { 182800b99b8Sopenharmony_ci GetNextLine(ehdrFP_, &status); 183800b99b8Sopenharmony_ci } 184800b99b8Sopenharmony_ci if (!GetMachine(ehdrFP_)) { 185800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitMachine(ehdrFP_) failed:"); 186800b99b8Sopenharmony_ci } 187800b99b8Sopenharmony_ci 188800b99b8Sopenharmony_ci if (machine_ == "ARM") { 189800b99b8Sopenharmony_ci archType_ = ARCH_ARM; 190800b99b8Sopenharmony_ci } else if (machine_ == "80386") { 191800b99b8Sopenharmony_ci archType_ = ARCH_X86; 192800b99b8Sopenharmony_ci } else if (machine_ == "AARCH64") { 193800b99b8Sopenharmony_ci archType_ = ARCH_ARM64; 194800b99b8Sopenharmony_ci } else if (machine_ == "X86-64") { 195800b99b8Sopenharmony_ci archType_ = ARCH_X86_64; 196800b99b8Sopenharmony_ci } else { 197800b99b8Sopenharmony_ci DFXLOGW("Failed the machine = %{public}s", machine_.c_str()); 198800b99b8Sopenharmony_ci } 199800b99b8Sopenharmony_ci 200800b99b8Sopenharmony_ci if (!GetEntryAddr(ehdrFP_)) { 201800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitEntryAddr(ehdrFP_) failed:"); 202800b99b8Sopenharmony_ci return false; 203800b99b8Sopenharmony_ci } 204800b99b8Sopenharmony_ci if (!GetPrgOffset(ehdrFP_)) { 205800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitPrgOffset(ehdrFP_) failed:"); 206800b99b8Sopenharmony_ci return false; 207800b99b8Sopenharmony_ci } 208800b99b8Sopenharmony_ci if (!GetSecOffset(ehdrFP_)) { 209800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitSecOffset(ehdrFP_) failed:"); 210800b99b8Sopenharmony_ci return false; 211800b99b8Sopenharmony_ci } 212800b99b8Sopenharmony_ci if (!GetFlag(ehdrFP_)) { 213800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitFlag(ehdrFP_) failed:"); 214800b99b8Sopenharmony_ci return false; 215800b99b8Sopenharmony_ci } 216800b99b8Sopenharmony_ci if (!GetEhdrSize(ehdrFP_)) { 217800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitEhdrSize(ehdrFP_) failed:"); 218800b99b8Sopenharmony_ci return false; 219800b99b8Sopenharmony_ci } 220800b99b8Sopenharmony_ci if (!GetPhdrSize(ehdrFP_)) { 221800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitPhdrSize(ehdrFP_) failed:"); 222800b99b8Sopenharmony_ci return false; 223800b99b8Sopenharmony_ci } 224800b99b8Sopenharmony_ci if (!GetNumPhdrs(ehdrFP_)) { 225800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitNumPhdrs(ehdrFP_) failed:"); 226800b99b8Sopenharmony_ci return false; 227800b99b8Sopenharmony_ci } 228800b99b8Sopenharmony_ci if (!GetShdrSize(ehdrFP_)) { 229800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitShdrSize(ehdrFP_) failed:"); 230800b99b8Sopenharmony_ci return false; 231800b99b8Sopenharmony_ci } 232800b99b8Sopenharmony_ci if (!GetNumShdrs(ehdrFP_)) { 233800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitNumShdrs(ehdrFP_) failed:"); 234800b99b8Sopenharmony_ci return false; 235800b99b8Sopenharmony_ci } 236800b99b8Sopenharmony_ci if (!GetShdrStrTabIdx(ehdrFP_)) { 237800b99b8Sopenharmony_ci DFXLOGE("ElfImitate::InitShdrStrTabIdx(ehdrFP_) failed:"); 238800b99b8Sopenharmony_ci return false; 239800b99b8Sopenharmony_ci } 240800b99b8Sopenharmony_ci elfSize_ = shdrOffset_ + shdrEntSize_ * shdrNumEnts_; 241800b99b8Sopenharmony_ci return true; 242800b99b8Sopenharmony_ci} 243800b99b8Sopenharmony_cibool ElfImitate::GetMagic(FILE * const fp) 244800b99b8Sopenharmony_ci{ 245800b99b8Sopenharmony_ci if (fp == nullptr) { 246800b99b8Sopenharmony_ci DFXLOGE("param is null"); 247800b99b8Sopenharmony_ci return false; 248800b99b8Sopenharmony_ci } 249800b99b8Sopenharmony_ci int status {0}; 250800b99b8Sopenharmony_ci std::string magicLine = GetNextLine(fp, &status); 251800b99b8Sopenharmony_ci if (status == -1) { 252800b99b8Sopenharmony_ci DFXLOGE("early end"); 253800b99b8Sopenharmony_ci return false; 254800b99b8Sopenharmony_ci } 255800b99b8Sopenharmony_ci auto tmp = StringSplit(magicLine, " "); 256800b99b8Sopenharmony_ci std::vector<std::string> strVec {tmp.begin() + 1, tmp.end()}; 257800b99b8Sopenharmony_ci if (strVec.size() != EI_NIDENT) { 258800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 259800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", magicLine.c_str()); 260800b99b8Sopenharmony_ci return false; 261800b99b8Sopenharmony_ci } 262800b99b8Sopenharmony_ci for (std::size_t count = 0; count < strVec.size(); ++count) { 263800b99b8Sopenharmony_ci std::string valStr = strVec[count]; 264800b99b8Sopenharmony_ci constexpr int base {16}; 265800b99b8Sopenharmony_ci ehdrIdent_[count] = static_cast<unsigned char>(std::stoul(valStr, nullptr, base)); 266800b99b8Sopenharmony_ci } 267800b99b8Sopenharmony_ci return true; 268800b99b8Sopenharmony_ci} 269800b99b8Sopenharmony_ci 270800b99b8Sopenharmony_cibool ElfImitate::GetClass(FILE * const fp) 271800b99b8Sopenharmony_ci{ 272800b99b8Sopenharmony_ci if (fp == nullptr) { 273800b99b8Sopenharmony_ci DFXLOGE("param is null"); 274800b99b8Sopenharmony_ci return false; 275800b99b8Sopenharmony_ci } 276800b99b8Sopenharmony_ci int status {0}; 277800b99b8Sopenharmony_ci std::string classLine = GetNextLine(fp, &status); 278800b99b8Sopenharmony_ci if (status == -1) { 279800b99b8Sopenharmony_ci DFXLOGE("early end"); 280800b99b8Sopenharmony_ci return false; 281800b99b8Sopenharmony_ci } 282800b99b8Sopenharmony_ci auto strVec = StringSplit(classLine, " "); 283800b99b8Sopenharmony_ci constexpr int len {2}; 284800b99b8Sopenharmony_ci if (strVec.size() != len) { 285800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 286800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", classLine.c_str()); 287800b99b8Sopenharmony_ci return false; 288800b99b8Sopenharmony_ci } 289800b99b8Sopenharmony_ci if (strVec.back() == "ELF32") { 290800b99b8Sopenharmony_ci classType_ = ELFCLASS32; 291800b99b8Sopenharmony_ci } else if (strVec.back() == "ELF64") { 292800b99b8Sopenharmony_ci classType_ = ELFCLASS64; 293800b99b8Sopenharmony_ci } 294800b99b8Sopenharmony_ci return true; 295800b99b8Sopenharmony_ci} 296800b99b8Sopenharmony_ci 297800b99b8Sopenharmony_cibool ElfImitate::GetMachine(FILE * const fp) 298800b99b8Sopenharmony_ci{ 299800b99b8Sopenharmony_ci int status {0}; 300800b99b8Sopenharmony_ci std::string machineLine = GetNextLine(fp, &status); 301800b99b8Sopenharmony_ci if (status == -1) { 302800b99b8Sopenharmony_ci DFXLOGE("early end"); 303800b99b8Sopenharmony_ci return false; 304800b99b8Sopenharmony_ci } 305800b99b8Sopenharmony_ci auto strVec = StringSplit(machineLine, " "); 306800b99b8Sopenharmony_ci constexpr int len {2}; 307800b99b8Sopenharmony_ci if (strVec.size() != len) { 308800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 309800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", machineLine.c_str()); 310800b99b8Sopenharmony_ci return false; 311800b99b8Sopenharmony_ci } 312800b99b8Sopenharmony_ci machine_ = strVec.back(); 313800b99b8Sopenharmony_ci return true; 314800b99b8Sopenharmony_ci} 315800b99b8Sopenharmony_cibool ElfImitate::GetEntryAddr(FILE * const fp) 316800b99b8Sopenharmony_ci{ 317800b99b8Sopenharmony_ci int status {0}; 318800b99b8Sopenharmony_ci std::string entryLine = GetNextLine(fp, &status); 319800b99b8Sopenharmony_ci if (status == -1) { 320800b99b8Sopenharmony_ci DFXLOGE("early end"); 321800b99b8Sopenharmony_ci return false; 322800b99b8Sopenharmony_ci } 323800b99b8Sopenharmony_ci auto strVec = StringSplit(entryLine, " "); 324800b99b8Sopenharmony_ci constexpr int len {2}; 325800b99b8Sopenharmony_ci if (strVec.size() != len) { 326800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 327800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", entryLine.c_str()); 328800b99b8Sopenharmony_ci return false; 329800b99b8Sopenharmony_ci } 330800b99b8Sopenharmony_ci std::string entryStr = strVec.back(); 331800b99b8Sopenharmony_ci constexpr int base {16}; 332800b99b8Sopenharmony_ci prgEntryVaddr_ = static_cast<uint64_t>(std::stoull(entryStr, nullptr, base)); 333800b99b8Sopenharmony_ci return true; 334800b99b8Sopenharmony_ci} 335800b99b8Sopenharmony_ci 336800b99b8Sopenharmony_cibool ElfImitate::GetPrgOffset(FILE * const fp) 337800b99b8Sopenharmony_ci{ 338800b99b8Sopenharmony_ci int status {0}; 339800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 340800b99b8Sopenharmony_ci if (status == -1) { 341800b99b8Sopenharmony_ci DFXLOGE("early end"); 342800b99b8Sopenharmony_ci return false; 343800b99b8Sopenharmony_ci } 344800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 345800b99b8Sopenharmony_ci constexpr int len {5}; 346800b99b8Sopenharmony_ci if (strVec.size() != len) { 347800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 348800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 349800b99b8Sopenharmony_ci return false; 350800b99b8Sopenharmony_ci } 351800b99b8Sopenharmony_ci constexpr int valIndex {1}; 352800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 353800b99b8Sopenharmony_ci phdrOffset_ = static_cast<uint64_t>(std::stoull(valStr)); 354800b99b8Sopenharmony_ci return true; 355800b99b8Sopenharmony_ci} 356800b99b8Sopenharmony_ci 357800b99b8Sopenharmony_cibool ElfImitate::GetSecOffset(FILE * const fp) 358800b99b8Sopenharmony_ci{ 359800b99b8Sopenharmony_ci int status {0}; 360800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 361800b99b8Sopenharmony_ci if (status == -1) { 362800b99b8Sopenharmony_ci DFXLOGE("early end"); 363800b99b8Sopenharmony_ci return false; 364800b99b8Sopenharmony_ci } 365800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 366800b99b8Sopenharmony_ci constexpr int len {8}; 367800b99b8Sopenharmony_ci if (strVec.size() != len) { 368800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 369800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 370800b99b8Sopenharmony_ci return false; 371800b99b8Sopenharmony_ci } 372800b99b8Sopenharmony_ci constexpr int valIndex {4}; 373800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 374800b99b8Sopenharmony_ci shdrOffset_ = static_cast<uint64_t>(std::stoull(valStr)); 375800b99b8Sopenharmony_ci return true; 376800b99b8Sopenharmony_ci} 377800b99b8Sopenharmony_ci 378800b99b8Sopenharmony_cibool ElfImitate::GetFlag(FILE * const fp) 379800b99b8Sopenharmony_ci{ 380800b99b8Sopenharmony_ci int status {0}; 381800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 382800b99b8Sopenharmony_ci if (status == -1) { 383800b99b8Sopenharmony_ci DFXLOGE("early end"); 384800b99b8Sopenharmony_ci return false; 385800b99b8Sopenharmony_ci } 386800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 387800b99b8Sopenharmony_ci constexpr int len {2}; 388800b99b8Sopenharmony_ci if (strVec.size() != len) { 389800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 390800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 391800b99b8Sopenharmony_ci return false; 392800b99b8Sopenharmony_ci } 393800b99b8Sopenharmony_ci constexpr int valIndex {1}; 394800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 395800b99b8Sopenharmony_ci ehdrFlags_ = static_cast<uint32_t>(std::stoul(valStr)); 396800b99b8Sopenharmony_ci return true; 397800b99b8Sopenharmony_ci} 398800b99b8Sopenharmony_ci 399800b99b8Sopenharmony_cibool ElfImitate::GetEhdrSize(FILE * const fp) 400800b99b8Sopenharmony_ci{ 401800b99b8Sopenharmony_ci int status {0}; 402800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 403800b99b8Sopenharmony_ci if (status == -1) { 404800b99b8Sopenharmony_ci DFXLOGE("early end"); 405800b99b8Sopenharmony_ci return false; 406800b99b8Sopenharmony_ci } 407800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 408800b99b8Sopenharmony_ci constexpr int len {6}; 409800b99b8Sopenharmony_ci if (strVec.size() != len) { 410800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 411800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 412800b99b8Sopenharmony_ci return false; 413800b99b8Sopenharmony_ci } 414800b99b8Sopenharmony_ci constexpr int valIndex {4}; 415800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 416800b99b8Sopenharmony_ci ehdrSize_ = static_cast<uint16_t>(std::stoull(valStr)); 417800b99b8Sopenharmony_ci return true; 418800b99b8Sopenharmony_ci} 419800b99b8Sopenharmony_ci 420800b99b8Sopenharmony_cibool ElfImitate::GetPhdrSize(FILE * const fp) 421800b99b8Sopenharmony_ci{ 422800b99b8Sopenharmony_ci int status {0}; 423800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 424800b99b8Sopenharmony_ci if (status == -1) { 425800b99b8Sopenharmony_ci DFXLOGE("early end"); 426800b99b8Sopenharmony_ci return false; 427800b99b8Sopenharmony_ci } 428800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 429800b99b8Sopenharmony_ci constexpr int len {6}; 430800b99b8Sopenharmony_ci if (strVec.size() != len) { 431800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 432800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 433800b99b8Sopenharmony_ci return false; 434800b99b8Sopenharmony_ci } 435800b99b8Sopenharmony_ci constexpr int valIndex {4}; 436800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 437800b99b8Sopenharmony_ci phdrEntSize_ = static_cast<uint16_t>(std::stoull(valStr)); 438800b99b8Sopenharmony_ci return true; 439800b99b8Sopenharmony_ci} 440800b99b8Sopenharmony_ci 441800b99b8Sopenharmony_cibool ElfImitate::GetNumPhdrs(FILE * const fp) 442800b99b8Sopenharmony_ci{ 443800b99b8Sopenharmony_ci int status {0}; 444800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 445800b99b8Sopenharmony_ci if (status == -1) { 446800b99b8Sopenharmony_ci DFXLOGE("early end"); 447800b99b8Sopenharmony_ci return false; 448800b99b8Sopenharmony_ci } 449800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 450800b99b8Sopenharmony_ci constexpr int len {5}; 451800b99b8Sopenharmony_ci if (strVec.size() != len) { 452800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 453800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 454800b99b8Sopenharmony_ci return false; 455800b99b8Sopenharmony_ci } 456800b99b8Sopenharmony_ci constexpr int valIndex {4}; 457800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 458800b99b8Sopenharmony_ci phdrNumEnts_ = static_cast<uint16_t>(std::stoull(valStr)); 459800b99b8Sopenharmony_ci return true; 460800b99b8Sopenharmony_ci} 461800b99b8Sopenharmony_ci 462800b99b8Sopenharmony_cibool ElfImitate::GetShdrSize(FILE * const fp) 463800b99b8Sopenharmony_ci{ 464800b99b8Sopenharmony_ci int status {0}; 465800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 466800b99b8Sopenharmony_ci if (status == -1) { 467800b99b8Sopenharmony_ci DFXLOGE("early end"); 468800b99b8Sopenharmony_ci return false; 469800b99b8Sopenharmony_ci } 470800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 471800b99b8Sopenharmony_ci constexpr int len {6}; 472800b99b8Sopenharmony_ci if (strVec.size() != len) { 473800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 474800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 475800b99b8Sopenharmony_ci return false; 476800b99b8Sopenharmony_ci } 477800b99b8Sopenharmony_ci constexpr int valIndex {4}; 478800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 479800b99b8Sopenharmony_ci shdrEntSize_ = static_cast<uint16_t>(std::stoull(valStr)); 480800b99b8Sopenharmony_ci return true; 481800b99b8Sopenharmony_ci} 482800b99b8Sopenharmony_ci 483800b99b8Sopenharmony_cibool ElfImitate::GetNumShdrs(FILE * const fp) 484800b99b8Sopenharmony_ci{ 485800b99b8Sopenharmony_ci int status {0}; 486800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 487800b99b8Sopenharmony_ci if (status == -1) { 488800b99b8Sopenharmony_ci DFXLOGE("early end"); 489800b99b8Sopenharmony_ci return false; 490800b99b8Sopenharmony_ci } 491800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 492800b99b8Sopenharmony_ci constexpr int len {5}; 493800b99b8Sopenharmony_ci if (strVec.size() != len) { 494800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 495800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 496800b99b8Sopenharmony_ci return false; 497800b99b8Sopenharmony_ci } 498800b99b8Sopenharmony_ci constexpr int valIndex {4}; 499800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 500800b99b8Sopenharmony_ci shdrNumEnts_ = static_cast<uint16_t>(std::stoull(valStr)); 501800b99b8Sopenharmony_ci return true; 502800b99b8Sopenharmony_ci} 503800b99b8Sopenharmony_ci 504800b99b8Sopenharmony_cibool ElfImitate::GetShdrStrTabIdx(FILE * const fp) 505800b99b8Sopenharmony_ci{ 506800b99b8Sopenharmony_ci int status {0}; 507800b99b8Sopenharmony_ci std::string line = GetNextLine(fp, &status); 508800b99b8Sopenharmony_ci if (status == -1) { 509800b99b8Sopenharmony_ci DFXLOGE("early end"); 510800b99b8Sopenharmony_ci return false; 511800b99b8Sopenharmony_ci } 512800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 513800b99b8Sopenharmony_ci constexpr int len {6}; 514800b99b8Sopenharmony_ci if (strVec.size() != len) { 515800b99b8Sopenharmony_ci DFXLOGE("line format incorrect:"); 516800b99b8Sopenharmony_ci DFXLOGE(" line = %{public}s", line.c_str()); 517800b99b8Sopenharmony_ci return false; 518800b99b8Sopenharmony_ci } 519800b99b8Sopenharmony_ci constexpr int valIndex {5}; 520800b99b8Sopenharmony_ci std::string valStr = strVec[valIndex]; 521800b99b8Sopenharmony_ci shdrStrTabIdx_ = static_cast<uint16_t>(std::stoull(valStr)); 522800b99b8Sopenharmony_ci return true; 523800b99b8Sopenharmony_ci} 524800b99b8Sopenharmony_ci 525800b99b8Sopenharmony_cibool ElfImitate::ParseProgramHeaders(ElfFileType fileType) 526800b99b8Sopenharmony_ci{ 527800b99b8Sopenharmony_ci bool firstLoadHeader = true; 528800b99b8Sopenharmony_ci while (true) { 529800b99b8Sopenharmony_ci std::string line {}; 530800b99b8Sopenharmony_ci line = GetNextPhdrLine(); 531800b99b8Sopenharmony_ci if (line.empty()) { 532800b99b8Sopenharmony_ci break; 533800b99b8Sopenharmony_ci DFXLOGI("no more program lines"); 534800b99b8Sopenharmony_ci } 535800b99b8Sopenharmony_ci if (fileType == ElfFileType::ELF64) { 536800b99b8Sopenharmony_ci int status = 0; 537800b99b8Sopenharmony_ci std::string lineAppend = GetNextLine(phdrFP_, &status); 538800b99b8Sopenharmony_ci if (status == -1) { 539800b99b8Sopenharmony_ci DFXLOGE("GetNextLine(phdrFP_, &status) error:"); 540800b99b8Sopenharmony_ci break; 541800b99b8Sopenharmony_ci } 542800b99b8Sopenharmony_ci if (lineAppend.empty()) { 543800b99b8Sopenharmony_ci break; 544800b99b8Sopenharmony_ci DFXLOGI("no more program lines"); 545800b99b8Sopenharmony_ci } 546800b99b8Sopenharmony_ci line += lineAppend; 547800b99b8Sopenharmony_ci } 548800b99b8Sopenharmony_ci 549800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 550800b99b8Sopenharmony_ci std::string type = strVec[0]; 551800b99b8Sopenharmony_ci int base = 16; // 16:HEX 552800b99b8Sopenharmony_ci uint64_t offset = std::stoull(strVec[INDEX_I1], nullptr, base); 553800b99b8Sopenharmony_ci uint64_t vAddr = std::stoull(strVec[INDEX_I2], nullptr, base); 554800b99b8Sopenharmony_ci uint64_t memSize = std::stoull(strVec[INDEX_I5], nullptr, base); 555800b99b8Sopenharmony_ci std::string flg = strVec[INDEX_I6]; 556800b99b8Sopenharmony_ci if (!std::all_of(strVec[INDEX_I7].begin(), strVec[INDEX_I7].end(), ::isdigit)) { 557800b99b8Sopenharmony_ci flg += strVec[INDEX_I7]; 558800b99b8Sopenharmony_ci } 559800b99b8Sopenharmony_ci if (type == "LOAD") { 560800b99b8Sopenharmony_ci if (flg.find("E") == std::string::npos) { 561800b99b8Sopenharmony_ci continue; 562800b99b8Sopenharmony_ci } 563800b99b8Sopenharmony_ci ptLoads_[offset] = ElfLoadInfo{offset, vAddr, static_cast<size_t>(memSize)}; 564800b99b8Sopenharmony_ci 565800b99b8Sopenharmony_ci // Only set the load bias from the first executable load header. 566800b99b8Sopenharmony_ci if (firstLoadHeader) { 567800b99b8Sopenharmony_ci loadBias_ = static_cast<int64_t>(static_cast<uint64_t>(vAddr) - offset); 568800b99b8Sopenharmony_ci } 569800b99b8Sopenharmony_ci firstLoadHeader = false; 570800b99b8Sopenharmony_ci 571800b99b8Sopenharmony_ci if (vAddr < startVaddr_) { 572800b99b8Sopenharmony_ci startVaddr_ = vAddr; 573800b99b8Sopenharmony_ci } 574800b99b8Sopenharmony_ci if (vAddr + memSize > endVaddr_) { 575800b99b8Sopenharmony_ci endVaddr_ = vAddr + memSize; 576800b99b8Sopenharmony_ci } 577800b99b8Sopenharmony_ci } 578800b99b8Sopenharmony_ci } 579800b99b8Sopenharmony_ci return true; 580800b99b8Sopenharmony_ci} 581800b99b8Sopenharmony_cibool ElfImitate::ParseSectionHeaders(ElfFileType fileType) 582800b99b8Sopenharmony_ci{ 583800b99b8Sopenharmony_ci std::string line {}; 584800b99b8Sopenharmony_ci int status = 0; 585800b99b8Sopenharmony_ci (void)GetNextShdrLine(); //skip index 0 section header 586800b99b8Sopenharmony_ci (void)GetNextLine(shdrFP_, &status); 587800b99b8Sopenharmony_ci while (true) { 588800b99b8Sopenharmony_ci status = 0; 589800b99b8Sopenharmony_ci line = GetNextShdrLine(); 590800b99b8Sopenharmony_ci if (line.empty()) { 591800b99b8Sopenharmony_ci break; 592800b99b8Sopenharmony_ci DFXLOGI("no more section lines"); 593800b99b8Sopenharmony_ci } 594800b99b8Sopenharmony_ci if (fileType == ElfFileType::ELF64) { 595800b99b8Sopenharmony_ci std::string lineAppend = GetNextLine(shdrFP_, &status); 596800b99b8Sopenharmony_ci if (lineAppend.empty()) { 597800b99b8Sopenharmony_ci break; 598800b99b8Sopenharmony_ci DFXLOGI("no more section lines"); 599800b99b8Sopenharmony_ci } 600800b99b8Sopenharmony_ci line += lineAppend; 601800b99b8Sopenharmony_ci } 602800b99b8Sopenharmony_ci 603800b99b8Sopenharmony_ci auto secIndex = GetSecIndex(line); 604800b99b8Sopenharmony_ci 605800b99b8Sopenharmony_ci auto pos = line.find("]"); 606800b99b8Sopenharmony_ci if (pos == std::string::npos) { 607800b99b8Sopenharmony_ci DFXLOGI("incorrect section line: %{public}s", line.c_str()); 608800b99b8Sopenharmony_ci return false; 609800b99b8Sopenharmony_ci } 610800b99b8Sopenharmony_ci ++pos; 611800b99b8Sopenharmony_ci std::string tmpLine = line.substr(pos, line.length() - pos); 612800b99b8Sopenharmony_ci auto strVec = StringSplit(tmpLine, " "); 613800b99b8Sopenharmony_ci for (size_t i = 0; i < strVec.size(); ++i) {} 614800b99b8Sopenharmony_ci 615800b99b8Sopenharmony_ci constexpr int base {16}; 616800b99b8Sopenharmony_ci std::string secName = strVec[0]; 617800b99b8Sopenharmony_ci std::string secType = strVec[1]; 618800b99b8Sopenharmony_ci uint64_t secAddr = std::stoull(strVec[2], nullptr, base); 619800b99b8Sopenharmony_ci uint64_t secOffset = std::stoull(strVec[3], nullptr, base); 620800b99b8Sopenharmony_ci uint64_t secSize = std::stoull(strVec[4], nullptr, base); 621800b99b8Sopenharmony_ci uint64_t secEntSize = std::stoull(strVec[5], nullptr, base); 622800b99b8Sopenharmony_ci uint64_t secLink = std::stoull(strVec[strVec.size() - 3], nullptr, base); 623800b99b8Sopenharmony_ci uint64_t secInfo = std::stoull(strVec[strVec.size() - 2], nullptr, base); 624800b99b8Sopenharmony_ci uint64_t secAddrAlign = std::stoull(strVec[strVec.size() - 1], nullptr, base); 625800b99b8Sopenharmony_ci 626800b99b8Sopenharmony_ci ShdrInfo shdrInfo; 627800b99b8Sopenharmony_ci shdrInfo.addr = secAddr; 628800b99b8Sopenharmony_ci shdrInfo.offset = secOffset; 629800b99b8Sopenharmony_ci shdrInfo.size = secSize; 630800b99b8Sopenharmony_ci shdrInfoPairs_.emplace(std::make_pair(secIndex, secName), shdrInfo); 631800b99b8Sopenharmony_ci 632800b99b8Sopenharmony_ci if (secType == "SYMTAB" || secType == "DYNSYM") { 633800b99b8Sopenharmony_ci ElfShdr elfShdr; 634800b99b8Sopenharmony_ci elfShdr.name = static_cast<uint32_t>(secIndex); 635800b99b8Sopenharmony_ci if (secType == "SYMTAB") { 636800b99b8Sopenharmony_ci elfShdr.type = static_cast<uint32_t>(SHT_SYMTAB); 637800b99b8Sopenharmony_ci } else { 638800b99b8Sopenharmony_ci elfShdr.type = static_cast<uint32_t>(SHT_DYNSYM); 639800b99b8Sopenharmony_ci } 640800b99b8Sopenharmony_ci 641800b99b8Sopenharmony_ci elfShdr.addr = secAddr; 642800b99b8Sopenharmony_ci elfShdr.offset = secOffset; 643800b99b8Sopenharmony_ci elfShdr.size = secSize; 644800b99b8Sopenharmony_ci elfShdr.link = static_cast<uint32_t>(secLink); 645800b99b8Sopenharmony_ci elfShdr.info = static_cast<uint32_t>(secInfo); 646800b99b8Sopenharmony_ci elfShdr.addrAlign = secAddrAlign; 647800b99b8Sopenharmony_ci elfShdr.entSize = secEntSize; 648800b99b8Sopenharmony_ci symShdrs_.emplace(secName, elfShdr); 649800b99b8Sopenharmony_ci } 650800b99b8Sopenharmony_ci } 651800b99b8Sopenharmony_ci return true; 652800b99b8Sopenharmony_ci} 653800b99b8Sopenharmony_ciconst std::string ElfImitate::GetNextPhdrLine() 654800b99b8Sopenharmony_ci{ 655800b99b8Sopenharmony_ci const std::string effectFlag {"0x00"}; 656800b99b8Sopenharmony_ci std::string line {}; 657800b99b8Sopenharmony_ci int status {0}; 658800b99b8Sopenharmony_ci while (true) { 659800b99b8Sopenharmony_ci line = GetNextLine(phdrFP_, &status); 660800b99b8Sopenharmony_ci if (status == -1) { 661800b99b8Sopenharmony_ci DFXLOGE("GetNextLine(phdrFP_, &status) error:"); 662800b99b8Sopenharmony_ci line = ""; 663800b99b8Sopenharmony_ci break; 664800b99b8Sopenharmony_ci } 665800b99b8Sopenharmony_ci if (line.find(effectFlag) != std::string::npos) { 666800b99b8Sopenharmony_ci DFXLOGE("effective program header line: %{public}s", line.c_str()); 667800b99b8Sopenharmony_ci break; 668800b99b8Sopenharmony_ci } 669800b99b8Sopenharmony_ci } 670800b99b8Sopenharmony_ci return line; 671800b99b8Sopenharmony_ci} 672800b99b8Sopenharmony_ci 673800b99b8Sopenharmony_ciconst std::string ElfImitate::GetNextShdrLine() 674800b99b8Sopenharmony_ci{ 675800b99b8Sopenharmony_ci const std::string effectFlag {"]"}; 676800b99b8Sopenharmony_ci std::string line {}; 677800b99b8Sopenharmony_ci int status {0}; 678800b99b8Sopenharmony_ci while (true) { 679800b99b8Sopenharmony_ci line = GetNextLine(shdrFP_, &status); 680800b99b8Sopenharmony_ci if (status == -1) { 681800b99b8Sopenharmony_ci DFXLOGE("GetNextLine(phdrFP_, &status) error:"); 682800b99b8Sopenharmony_ci line = ""; 683800b99b8Sopenharmony_ci break; 684800b99b8Sopenharmony_ci } 685800b99b8Sopenharmony_ci auto pos = line.find(effectFlag); 686800b99b8Sopenharmony_ci if ((pos != std::string::npos) and isdigit(line.at(pos - 1))) { 687800b99b8Sopenharmony_ci DFXLOGE("effective section header line: %{public}s", line.c_str()); 688800b99b8Sopenharmony_ci break; 689800b99b8Sopenharmony_ci } 690800b99b8Sopenharmony_ci } 691800b99b8Sopenharmony_ci return line; 692800b99b8Sopenharmony_ci} 693800b99b8Sopenharmony_ciint64_t ElfImitate::GetSecIndex(const std::string &line) 694800b99b8Sopenharmony_ci{ 695800b99b8Sopenharmony_ci int64_t res {-1}; 696800b99b8Sopenharmony_ci auto pos = line.find("["); 697800b99b8Sopenharmony_ci if (pos == std::string::npos) { 698800b99b8Sopenharmony_ci DFXLOGI("no section index found: %{public}s", line.c_str()); 699800b99b8Sopenharmony_ci return res; 700800b99b8Sopenharmony_ci } 701800b99b8Sopenharmony_ci constexpr int len {4}; 702800b99b8Sopenharmony_ci std::string str = line.substr(pos, len); 703800b99b8Sopenharmony_ci if (str.length() != len) { 704800b99b8Sopenharmony_ci DFXLOGI("section index form incorrect: %{public}s", str.c_str()); 705800b99b8Sopenharmony_ci return res; 706800b99b8Sopenharmony_ci } 707800b99b8Sopenharmony_ci // section index is of the form "[xx]" 708800b99b8Sopenharmony_ci constexpr int firstDigit {1}; 709800b99b8Sopenharmony_ci constexpr int numDigits {2}; 710800b99b8Sopenharmony_ci str = str.substr(firstDigit, numDigits); 711800b99b8Sopenharmony_ci if (str[0] == ' ') { 712800b99b8Sopenharmony_ci // str = [ x], transform it to [xx] 713800b99b8Sopenharmony_ci str[0] = '0'; 714800b99b8Sopenharmony_ci } 715800b99b8Sopenharmony_ci if (!str.empty() && std::all_of(str.begin(), str.end(), ::isdigit)) { 716800b99b8Sopenharmony_ci res = std::stoll(str); 717800b99b8Sopenharmony_ci } else { 718800b99b8Sopenharmony_ci DFXLOGI("not digits: %{public}s", str.c_str()); 719800b99b8Sopenharmony_ci } 720800b99b8Sopenharmony_ci return res; 721800b99b8Sopenharmony_ci} 722800b99b8Sopenharmony_ci 723800b99b8Sopenharmony_cibool ElfImitate::ParseElfSymbols() 724800b99b8Sopenharmony_ci{ 725800b99b8Sopenharmony_ci std::unordered_map <std::string, uint8_t> typeMap = { 726800b99b8Sopenharmony_ci {"OBJECT", STT_OBJECT}, {"FUNC", STT_FUNC}, {"SECTION", STT_SECTION}, {"FILE", STT_FILE}, 727800b99b8Sopenharmony_ci {"COMMON", STT_COMMON}, {"TLS", STT_TLS}, {"NUM", STT_NUM}, {"LOOS", STT_LOOS}, 728800b99b8Sopenharmony_ci {"GNU_IFUNC", STT_GNU_IFUNC}, {"HIOS", STT_HIOS}, {"LOPROC", STT_LOPROC}, {"HIPROC", STT_HIPROC}, 729800b99b8Sopenharmony_ci }; 730800b99b8Sopenharmony_ci std::unordered_map <std::string, uint8_t> bindMap = { 731800b99b8Sopenharmony_ci {"LOCAL", STB_LOCAL}, {"GLOBAL", STB_GLOBAL}, {"WEAK", STB_WEAK}, {"NUM", STB_NUM}, {"LOOS", STB_LOOS}, 732800b99b8Sopenharmony_ci {"GNU_UNIQUE", STB_GNU_UNIQUE}, {"HIOS", STB_HIOS}, {"LOPROC", STB_LOPROC}, {"HIPROC", STB_HIPROC} 733800b99b8Sopenharmony_ci }; 734800b99b8Sopenharmony_ci std::unordered_map <std::string, uint8_t> vsMap = { 735800b99b8Sopenharmony_ci {"DEFAULT", STV_DEFAULT}, {"INTERNAL", STV_INTERNAL}, {"HIDDEN", STV_HIDDEN}, {"PROTECTED", STV_PROTECTED}, 736800b99b8Sopenharmony_ci }; 737800b99b8Sopenharmony_ci while (true) { 738800b99b8Sopenharmony_ci std::string line {}; 739800b99b8Sopenharmony_ci line = GetNextSymLine(); 740800b99b8Sopenharmony_ci if (line.empty()) { 741800b99b8Sopenharmony_ci DFXLOGI("no more symbol lines"); 742800b99b8Sopenharmony_ci break; 743800b99b8Sopenharmony_ci } 744800b99b8Sopenharmony_ci auto strVec = StringSplit(line, " "); 745800b99b8Sopenharmony_ci ElfSymbol elfSymbol; 746800b99b8Sopenharmony_ci constexpr int base {16}; // 16:HEX 747800b99b8Sopenharmony_ci elfSymbol.name = std::stoul(strVec[INDEX_I0].substr(0, strVec[INDEX_I0].size() -1)); 748800b99b8Sopenharmony_ci elfSymbol.value = std::stoull(strVec[INDEX_I1], nullptr, base); 749800b99b8Sopenharmony_ci elfSymbol.size = std::stoull(strVec[INDEX_I2]); 750800b99b8Sopenharmony_ci elfSymbol.info = ELF32_ST_INFO(bindMap[strVec[INDEX_I4]], typeMap[strVec[INDEX_I3]]); 751800b99b8Sopenharmony_ci elfSymbol.other = vsMap["strVec[INDEX_I5]"]; 752800b99b8Sopenharmony_ci if (strVec[INDEX_I6] == "UND") { 753800b99b8Sopenharmony_ci elfSymbol.shndx = SHN_UNDEF; 754800b99b8Sopenharmony_ci } else if (strVec[INDEX_I6] == "ABS") { 755800b99b8Sopenharmony_ci elfSymbol.shndx = SHN_ABS; 756800b99b8Sopenharmony_ci } else { 757800b99b8Sopenharmony_ci elfSymbol.shndx = static_cast<uint16_t>(std::stoul(strVec[INDEX_I6])); 758800b99b8Sopenharmony_ci } 759800b99b8Sopenharmony_ci elfSymbols_.push_back(elfSymbol); 760800b99b8Sopenharmony_ci } 761800b99b8Sopenharmony_ci return true; 762800b99b8Sopenharmony_ci} 763800b99b8Sopenharmony_ciconst std::string ElfImitate::GetNextSymLine() 764800b99b8Sopenharmony_ci{ 765800b99b8Sopenharmony_ci const std::string effectFlag {":"}; 766800b99b8Sopenharmony_ci std::string line {}; 767800b99b8Sopenharmony_ci int status {0}; 768800b99b8Sopenharmony_ci while (true) { 769800b99b8Sopenharmony_ci line = GetNextLine(symTabFP_, &status); 770800b99b8Sopenharmony_ci if (status == -1) { 771800b99b8Sopenharmony_ci DFXLOGI("GetNextLine(phdrFP_, &status) error:"); 772800b99b8Sopenharmony_ci line = ""; 773800b99b8Sopenharmony_ci break; 774800b99b8Sopenharmony_ci } 775800b99b8Sopenharmony_ci auto pos = line.find(effectFlag); 776800b99b8Sopenharmony_ci if ((pos != std::string::npos) and isdigit(line.at(pos - 1))) { 777800b99b8Sopenharmony_ci DFXLOGI("effective symbol line: %{public}s", line.c_str()); 778800b99b8Sopenharmony_ci break; 779800b99b8Sopenharmony_ci } 780800b99b8Sopenharmony_ci } 781800b99b8Sopenharmony_ci return line; 782800b99b8Sopenharmony_ci} 783800b99b8Sopenharmony_ci 784800b99b8Sopenharmony_cibool ElfImitate::GetSectionInfo(ShdrInfo& shdr, const std::string secName) 785800b99b8Sopenharmony_ci{ 786800b99b8Sopenharmony_ci for (const auto &iter: shdrInfoPairs_) { 787800b99b8Sopenharmony_ci auto tmpPair = iter.first; 788800b99b8Sopenharmony_ci if (tmpPair.second == secName) { 789800b99b8Sopenharmony_ci shdr = iter.second; 790800b99b8Sopenharmony_ci return true; 791800b99b8Sopenharmony_ci } 792800b99b8Sopenharmony_ci } 793800b99b8Sopenharmony_ci return false; 794800b99b8Sopenharmony_ci} 795800b99b8Sopenharmony_ci 796800b99b8Sopenharmony_ciconst std::vector<ElfSymbol>& ElfImitate::GetElfSymbols() 797800b99b8Sopenharmony_ci{ 798800b99b8Sopenharmony_ci if (elfSymbols_.empty()) { 799800b99b8Sopenharmony_ci ParseElfSymbols(); 800800b99b8Sopenharmony_ci } 801800b99b8Sopenharmony_ci return elfSymbols_; 802800b99b8Sopenharmony_ci} 803800b99b8Sopenharmony_ciuint64_t ElfImitate::GetLoadBase(uint64_t mapStart, uint64_t mapOffset) 804800b99b8Sopenharmony_ci{ 805800b99b8Sopenharmony_ci loadBase_ = mapStart - mapOffset - GetLoadBias(); 806800b99b8Sopenharmony_ci 807800b99b8Sopenharmony_ci return loadBase_; 808800b99b8Sopenharmony_ci} 809800b99b8Sopenharmony_ci 810800b99b8Sopenharmony_ciuint64_t ElfImitate::GetStartPc() 811800b99b8Sopenharmony_ci{ 812800b99b8Sopenharmony_ci auto startVaddr = GetStartVaddr(); 813800b99b8Sopenharmony_ci startPc_ = startVaddr + loadBase_; 814800b99b8Sopenharmony_ci return startPc_; 815800b99b8Sopenharmony_ci} 816800b99b8Sopenharmony_ci 817800b99b8Sopenharmony_ciuint64_t ElfImitate::GetEndPc() 818800b99b8Sopenharmony_ci{ 819800b99b8Sopenharmony_ci auto endVaddr = GetEndVaddr(); 820800b99b8Sopenharmony_ci endPc_ = endVaddr + loadBase_; 821800b99b8Sopenharmony_ci return endPc_; 822800b99b8Sopenharmony_ci} 823800b99b8Sopenharmony_ci 824800b99b8Sopenharmony_ciuint64_t ElfImitate::GetRelPc(uint64_t pc, uint64_t mapStart, uint64_t mapOffset) 825800b99b8Sopenharmony_ci{ 826800b99b8Sopenharmony_ci return (pc - GetLoadBase(mapStart, mapOffset)); 827800b99b8Sopenharmony_ci} 828800b99b8Sopenharmony_ci 829800b99b8Sopenharmony_cibool ElfImitate::IsFunc(const ElfSymbol symbol) 830800b99b8Sopenharmony_ci{ 831800b99b8Sopenharmony_ci return ((symbol.shndx != SHN_UNDEF) && 832800b99b8Sopenharmony_ci (ELF32_ST_TYPE(symbol.info) == STT_FUNC || ELF32_ST_TYPE(symbol.info) == STT_GNU_IFUNC)); 833800b99b8Sopenharmony_ci} 834800b99b8Sopenharmony_ci 835800b99b8Sopenharmony_cibool ElfImitate::ParseSymbols(std::vector<DfxSymbol>& symbols, const std::string& filePath) 836800b99b8Sopenharmony_ci{ 837800b99b8Sopenharmony_ci std::vector<ElfSymbol> elfSymbols = GetElfSymbols(); 838800b99b8Sopenharmony_ci for (auto elfSymbol : elfSymbols) { 839800b99b8Sopenharmony_ci if (IsFunc(elfSymbol)) { 840800b99b8Sopenharmony_ci if (elfSymbol.value == 0 || elfSymbol.size == 0) { 841800b99b8Sopenharmony_ci continue; 842800b99b8Sopenharmony_ci } 843800b99b8Sopenharmony_ci std::string nameStr = ""; 844800b99b8Sopenharmony_ci symbols.emplace_back(elfSymbol.value, elfSymbol.size, 845800b99b8Sopenharmony_ci nameStr, DfxSymbols::Demangle(nameStr), filePath); 846800b99b8Sopenharmony_ci } else { 847800b99b8Sopenharmony_ci continue; 848800b99b8Sopenharmony_ci } 849800b99b8Sopenharmony_ci } 850800b99b8Sopenharmony_ci auto comp = [](DfxSymbol a, DfxSymbol b) { return a.funcVaddr_ < b.funcVaddr_; }; 851800b99b8Sopenharmony_ci std::sort(symbols.begin(), symbols.end(), comp); 852800b99b8Sopenharmony_ci auto pred = [](DfxSymbol a, DfxSymbol b) { return a.funcVaddr_ == b.funcVaddr_; }; 853800b99b8Sopenharmony_ci symbols.erase(std::unique(symbols.begin(), symbols.end(), pred), symbols.end()); 854800b99b8Sopenharmony_ci symbols.shrink_to_fit(); 855800b99b8Sopenharmony_ci return true; 856800b99b8Sopenharmony_ci} 857800b99b8Sopenharmony_ci 858800b99b8Sopenharmony_cibool ElfImitate::AddSymbolsByPlt(std::vector<DfxSymbol>& symbols, const std::string& filePath) 859800b99b8Sopenharmony_ci{ 860800b99b8Sopenharmony_ci ShdrInfo shdr; 861800b99b8Sopenharmony_ci GetSectionInfo(shdr, PLT); 862800b99b8Sopenharmony_ci symbols.emplace_back(shdr.addr, shdr.size, PLT, filePath); 863800b99b8Sopenharmony_ci return true; 864800b99b8Sopenharmony_ci} 865800b99b8Sopenharmony_ci 866800b99b8Sopenharmony_cibool ElfImitate::GetFuncNameAndOffset(uint64_t pc, std::string& funcName, uint64_t& start, uint64_t& end) 867800b99b8Sopenharmony_ci{ 868800b99b8Sopenharmony_ci std::vector<DfxSymbol> symbols; 869800b99b8Sopenharmony_ci if (!ParseSymbols(symbols, "")) { 870800b99b8Sopenharmony_ci return false; 871800b99b8Sopenharmony_ci } 872800b99b8Sopenharmony_ci 873800b99b8Sopenharmony_ci for (const auto& symbol : symbols) { 874800b99b8Sopenharmony_ci if (symbol.Contain(pc)) { 875800b99b8Sopenharmony_ci funcName = symbol.demangle_; 876800b99b8Sopenharmony_ci start = symbol.funcVaddr_; 877800b99b8Sopenharmony_ci end = symbol.funcVaddr_ + symbol.size_; 878800b99b8Sopenharmony_ci return true; 879800b99b8Sopenharmony_ci } 880800b99b8Sopenharmony_ci } 881800b99b8Sopenharmony_ci return false; 882800b99b8Sopenharmony_ci} 883800b99b8Sopenharmony_ci} // namespace HiviewDFX 884800b99b8Sopenharmony_ci} // namespace OHOS