• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &region);
56     void PtLoadFill(Elf64_Phdr &ph, const DumpMemoryRegions &region);
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 &regset)
82     {
83         struct iovec iov;
84         iov.iov_base = &regset;
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