1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef DFX_COREDUMP_WRITER_H 16 #define DFX_COREDUMP_WRITER_H 17 #if defined(__aarch64__) 18 19 #include <elf.h> 20 #include <sys/procfs.h> 21 #include <sys/uio.h> 22 23 #include "dfx_coredump_common.h" 24 #include "dfx_regs.h" 25 #include "dfx_log.h" 26 #include "securec.h" 27 28 namespace OHOS { 29 namespace HiviewDFX { 30 class Writer { 31 public: Writer(char * mappedMemory,char * currentPointer)32 Writer(char* mappedMemory, char* currentPointer) : mappedMemory_(mappedMemory), 33 currentPointer_(currentPointer) {} 34 virtual ~Writer() = default; 35 virtual char* Write() = 0; 36 protected: CopyAndAdvance(const void * src,size_t size)37 bool CopyAndAdvance(const void* src, size_t size) 38 { 39 if (memcpy_s(currentPointer_, size, src, size) != EOK) { 40 return false; 41 } 42 currentPointer_ += size; 43 return true; 44 } 45 char* mappedMemory_; 46 char* currentPointer_; 47 }; 48 49 class ProgramSegmentHeaderWriter : public Writer { 50 public: ProgramSegmentHeaderWriter(char * mappedMemory,char * currentPointer,Elf64_Half & ePhnum,std::vector<DumpMemoryRegions> & maps)51 ProgramSegmentHeaderWriter(char* mappedMemory, char* currentPointer, Elf64_Half& ePhnum, 52 std::vector<DumpMemoryRegions>& maps) : Writer(mappedMemory, currentPointer), ePhnum_(ePhnum), maps_(maps) {} 53 char* Write() override; 54 private: 55 void ProgramSegmentHeaderFill(Elf64_Phdr &ph, Elf64_Word pType, Elf64_Word pFlags, const DumpMemoryRegions ®ion); 56 void PtLoadFill(Elf64_Phdr &ph, const DumpMemoryRegions ®ion); 57 void PtNoteFill(Elf64_Phdr &ph); 58 Elf64_Half& ePhnum_; 59 std::vector<DumpMemoryRegions> maps_; 60 }; 61 62 class LoadSegmentWriter : public Writer { 63 public: LoadSegmentWriter(char * mappedMemory,char * currentPointer,pid_t pid,Elf64_Half ePhnum)64 LoadSegmentWriter(char* mappedMemory, char* currentPointer, pid_t pid, Elf64_Half ePhnum) 65 : Writer(mappedMemory, currentPointer), pid_(pid), ePhnum_(ePhnum) {} 66 char* Write() override; 67 private: 68 void ReadProcessVmmem(Elf64_Phdr &ptLoad); 69 pid_t pid_; 70 Elf64_Half ePhnum_; 71 }; 72 73 class NoteSegmentWriter : public Writer { 74 public: NoteSegmentWriter(char * mappedMemory,char * currentPointer,CoreDumpThread & coreDumpThread,std::vector<DumpMemoryRegions> & maps,std::shared_ptr<DfxRegs> regs)75 NoteSegmentWriter(char* mappedMemory, char* currentPointer, CoreDumpThread& coreDumpThread, 76 std::vector<DumpMemoryRegions>& maps, std::shared_ptr<DfxRegs> regs) : Writer(mappedMemory, currentPointer), 77 pid_(coreDumpThread.targetPid), targetTid_(coreDumpThread.targetTid), maps_(maps), keyRegs_(regs) {} 78 char* Write() override; 79 void SetKeyThreadData(CoreDumpKeyThreadData coreDumpKeyThreadData); 80 template<typename T> GetRegset(pid_t tid,int regsetType,T & regset)81 static bool GetRegset(pid_t tid, int regsetType, T ®set) 82 { 83 struct iovec iov; 84 iov.iov_base = ®set; 85 iov.iov_len = sizeof(T); 86 87 if (ptrace(PTRACE_GETREGSET, tid, regsetType, &iov) == -1) { 88 DFXLOGE("ptrace failed regsetType:%{public}d, tid:%{public}d, errno:%{public}d", regsetType, tid, errno); 89 return false; 90 } 91 return true; 92 } 93 template<typename T> GetSiginfoCommon(T & targetInfo,pid_t tid)94 static bool GetSiginfoCommon(T &targetInfo, pid_t tid) 95 { 96 if (ptrace(PTRACE_GETSIGINFO, tid, nullptr, &targetInfo) == -1) { 97 DFXLOGE("ptrace failed PTRACE_GETSIGINFO, tid:%{public}d, errno:%{public}d", tid, errno); 98 return false; 99 } 100 return true; 101 } 102 103 private: 104 bool PrpsinfoWrite(); 105 bool NoteWrite(uint32_t noteType, size_t descSize, const char* noteName); 106 void FillPrpsinfo(prpsinfo_t &ntPrpsinfo); 107 bool ReadProcessStat(prpsinfo_t &ntPrpsinfo); 108 bool ReadProcessStatus(prpsinfo_t &ntPrpsinfo); 109 bool ReadProcessComm(prpsinfo_t &ntPrpsinfo); 110 bool ReadProcessCmdline(prpsinfo_t &ntPrpsinfo); 111 bool MultiThreadNoteWrite(); 112 void ThreadNoteWrite(pid_t tid); 113 bool PrstatusWrite(pid_t tid); 114 bool ArmPacMaskWrite(pid_t tid); 115 bool FpregsetWrite(pid_t tid); 116 bool SiginfoWrite(pid_t tid); 117 bool ArmTaggedAddrCtrlWrite(); 118 bool GetPrStatus(prstatus_t &ntPrstatus, pid_t tid); 119 bool GetRusage(prstatus_t &ntPrstatus); 120 bool GetPrReg(prstatus_t &ntPrstatus, pid_t tid); 121 bool AuxvWrite(); 122 bool ReadProcessAuxv(Elf64_Nhdr *note); 123 bool FileWrite(); 124 bool WriteAddrRelated(); 125 bool WriteFilePath(Elf64_Half &lineNumber); 126 pid_t pid_; 127 pid_t targetTid_; 128 std::vector<DumpMemoryRegions> maps_; 129 std::shared_ptr<DfxRegs> keyRegs_; 130 CoreDumpKeyThreadData coreDumpKeyThreadData_; 131 }; 132 133 class SectionHeaderTableWriter : public Writer { 134 public: SectionHeaderTableWriter(char * mappedMemory,char * currentPointer)135 SectionHeaderTableWriter(char* mappedMemory, char* currentPointer) 136 : Writer(mappedMemory, currentPointer) {} 137 char* Write() override; 138 private: 139 void SectionHeaderFill(Elf64_Shdr *sectionHeader, Elf64_Word shType, Elf64_Xword shFlag, Elf64_Phdr *programHeader); 140 void AdjustOffset(uint8_t remain); 141 }; 142 143 } // namespace HiviewDFX 144 } // namespace OHOS 145 #endif 146 #endif