• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include <elf_parser.h>
17 
18 namespace OHOS {
19 namespace Developtools {
20 namespace NativeDaemon {
21 namespace ELF {
MakeUnique(unsigned char * const ehdrBuf,const std::size_t bufSize)22 std::unique_ptr<ElfHeader> ElfHeader::MakeUnique(unsigned char * const ehdrBuf,
23                                                  const std::size_t bufSize)
24 {
25     std::unique_ptr<ElfHeader> ehdr {new (std::nothrow) ElfHeader()};
26     if (ehdr == nullptr) {
27         HLOGV("ElfHeader() failed");
28         return nullptr;
29     }
30     if (!ehdr->Init(ehdrBuf, bufSize)) {
31         HLOGV("ElfHeader::Init(ehdrBuf, bufSize) failed\n");
32         DumpEhdrBuf(reinterpret_cast<char *>(ehdrBuf), bufSize);
33         return nullptr;
34     }
35     return ehdr;
36 }
37 
Init(unsigned char * const ehdrBuf,const std::size_t bufSize)38 bool ElfHeader::Init(unsigned char * const ehdrBuf, const std::size_t bufSize)
39 {
40     std::string magicStr {ehdrBuf, ehdrBuf + SELFMAG};
41     std::string elfMagic {ELFMAG};
42     if (magicStr.compare(elfMagic) != 0) {
43         HLOGE("elf magic not found");
44         return false;
45     }
46     if (memcpy_s(ehdrIdent_, EI_NIDENT, ehdrBuf, EI_NIDENT) != EOK) {
47         HLOGE("init ehdrIdent_ failed");
48         return false;
49     }
50     if (ehdrBuf[EI_CLASS] == ELFCLASS32 and ParseElf32Header(ehdrBuf, bufSize)) {
51         return true;
52     }
53     if (ehdrBuf[EI_CLASS] == ELFCLASS64 and ParseElf64Header(ehdrBuf, bufSize)) {
54         return true;
55     }
56     HLOGE("init elf header failed, elf header buffer dumped");
57     return false;
58 }
59 
ParseElf32Header(unsigned char * const ehdrBuf,const std::size_t bufSize)60 bool ElfHeader::ParseElf32Header(unsigned char * const ehdrBuf, const std::size_t bufSize)
61 {
62     if (bufSize < ehdr32Size) {
63         HLOGE("bad elf32 header buffer");
64         return false;
65     }
66     size_t curIndex {EI_NIDENT};
67     uint16_t *u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
68     type_ = u2Buf[0];
69     curIndex += sizeof(uint16_t);
70 
71     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
72     machine_ = u2Buf[0];
73     curIndex += sizeof(uint16_t);
74 
75     uint32_t *u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
76     elfVersion_ = u4Buf[0];
77     curIndex += sizeof(uint32_t);
78 
79     u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
80     prgEntryVaddr_ = u4Buf[0];
81     curIndex += sizeof(uint32_t);
82 
83     u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
84     phdrOffset_ = u4Buf[0];
85     curIndex += sizeof(uint32_t);
86 
87     u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
88     shdrOffset_ = u4Buf[0];
89     curIndex += sizeof(uint32_t);
90 
91     u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
92     ehdrFlags_ = u4Buf[0];
93     curIndex += sizeof(uint32_t);
94 
95     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
96     ehdrSize_ = u2Buf[0];
97     curIndex += sizeof(uint16_t);
98 
99     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
100     phdrEntSize_ = u2Buf[0];
101     curIndex += sizeof(uint16_t);
102 
103     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
104     phdrNumEnts_ = u2Buf[0];
105     curIndex += sizeof(uint16_t);
106 
107     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
108     shdrEntSize_ = u2Buf[0];
109     curIndex += sizeof(uint16_t);
110 
111     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
112     shdrNumEnts_ = u2Buf[0];
113     curIndex += sizeof(uint16_t);
114 
115     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
116     shdrStrTabIdx_ = u2Buf[0];
117 
118 #ifdef HIPERF_DEBUG_ASSERT
119     curIndex += sizeof(uint16_t);
120     HLOG_ASSERT(curIndex == ehdrSize_);
121     HLOG_ASSERT(shdr32Size == ehdrSize_);
122 #endif
123     return true;
124 }
125 
ParseElf64Header(unsigned char * const ehdrBuf,const std::size_t bufSize)126 bool ElfHeader::ParseElf64Header(unsigned char * const ehdrBuf, const std::size_t bufSize)
127 {
128     if (bufSize < ehdr64Size) {
129         HLOGE("bad elf64 header buffer");
130         return false;
131     }
132     size_t curIndex {EI_NIDENT};
133     uint16_t *u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
134     type_ = u2Buf[0];
135     curIndex += sizeof(uint16_t);
136 
137     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
138     machine_ = u2Buf[0];
139     curIndex += sizeof(uint16_t);
140 
141     uint32_t *u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
142     elfVersion_ = u4Buf[0];
143     curIndex += sizeof(uint32_t);
144 
145     uint64_t *u8Buf = reinterpret_cast<uint64_t *>(ehdrBuf + curIndex);
146     prgEntryVaddr_ = u8Buf[0];
147     curIndex += sizeof(uint64_t);
148 
149     u8Buf = reinterpret_cast<uint64_t *>(ehdrBuf + curIndex);
150     phdrOffset_ = u8Buf[0];
151     curIndex += sizeof(uint64_t);
152 
153     u8Buf = reinterpret_cast<uint64_t *>(ehdrBuf + curIndex);
154     shdrOffset_ = u8Buf[0];
155     curIndex += sizeof(uint64_t);
156 
157     u4Buf = reinterpret_cast<uint32_t *>(ehdrBuf + curIndex);
158     ehdrFlags_ = u4Buf[0];
159     curIndex += sizeof(uint32_t);
160 
161     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
162     ehdrSize_ = u2Buf[0];
163     curIndex += sizeof(uint16_t);
164 
165     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
166     phdrEntSize_ = u2Buf[0];
167     curIndex += sizeof(uint16_t);
168 
169     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
170     phdrNumEnts_ = u2Buf[0];
171     curIndex += sizeof(uint16_t);
172 
173     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
174     shdrEntSize_ = u2Buf[0];
175     curIndex += sizeof(uint16_t);
176 
177     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
178     shdrNumEnts_ = static_cast<long long>(*u2Buf);
179     curIndex += sizeof(uint16_t);
180 
181     u2Buf = reinterpret_cast<uint16_t *>(ehdrBuf + curIndex);
182     shdrStrTabIdx_ = u2Buf[0];
183 
184 #ifdef HIPERF_DEBUG_ASSERT
185     curIndex += sizeof(uint16_t);
186     HLOG_ASSERT(curIndex == ehdrSize_);
187     HLOG_ASSERT(shdr64Size == ehdrSize_);
188 #endif
189     return true;
190 }
191 } // namespace ELF
192 } // namespace NativeDaemon
193 } // namespace Developtools
194 } // namespace OHOS