1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <elf.h> 18 #include <stdint.h> 19 20 #include <memory> 21 #include <string> 22 23 #include <7zCrc.h> 24 #include <Xz.h> 25 #include <XzCrc64.h> 26 27 #include <unwindstack/DwarfSection.h> 28 #include <unwindstack/ElfInterface.h> 29 #include <unwindstack/Log.h> 30 #include <unwindstack/Memory.h> 31 #include <unwindstack/Regs.h> 32 33 #include "DwarfDebugFrame.h" 34 #include "DwarfEhFrame.h" 35 #include "Symbols.h" 36 37 namespace unwindstack { 38 39 ElfInterface::~ElfInterface() { 40 for (auto symbol : symbols_) { 41 delete symbol; 42 } 43 } 44 45 Memory* ElfInterface::CreateGnuDebugdataMemory() { 46 if (gnu_debugdata_offset_ == 0 || gnu_debugdata_size_ == 0) { 47 return nullptr; 48 } 49 50 // TODO: Only call these initialization functions once. 51 CrcGenerateTable(); 52 Crc64GenerateTable(); 53 54 std::vector<uint8_t> src(gnu_debugdata_size_); 55 if (!memory_->Read(gnu_debugdata_offset_, src.data(), gnu_debugdata_size_)) { 56 gnu_debugdata_offset_ = 0; 57 gnu_debugdata_size_ = static_cast<uint64_t>(-1); 58 return nullptr; 59 } 60 61 ISzAlloc alloc; 62 CXzUnpacker state; 63 alloc.Alloc = [](void*, size_t size) { return malloc(size); }; 64 alloc.Free = [](void*, void* ptr) { return free(ptr); }; 65 66 XzUnpacker_Construct(&state, &alloc); 67 68 std::unique_ptr<MemoryBuffer> dst(new MemoryBuffer); 69 int return_val; 70 size_t src_offset = 0; 71 size_t dst_offset = 0; 72 ECoderStatus status; 73 dst->Resize(5 * gnu_debugdata_size_); 74 do { 75 size_t src_remaining = src.size() - src_offset; 76 size_t dst_remaining = dst->Size() - dst_offset; 77 if (dst_remaining < 2 * gnu_debugdata_size_) { 78 dst->Resize(dst->Size() + 2 * gnu_debugdata_size_); 79 dst_remaining += 2 * gnu_debugdata_size_; 80 } 81 return_val = XzUnpacker_Code(&state, dst->GetPtr(dst_offset), &dst_remaining, &src[src_offset], 82 &src_remaining, CODER_FINISH_ANY, &status); 83 src_offset += src_remaining; 84 dst_offset += dst_remaining; 85 } while (return_val == SZ_OK && status == CODER_STATUS_NOT_FINISHED); 86 XzUnpacker_Free(&state); 87 if (return_val != SZ_OK || !XzUnpacker_IsStreamWasFinished(&state)) { 88 gnu_debugdata_offset_ = 0; 89 gnu_debugdata_size_ = static_cast<uint64_t>(-1); 90 return nullptr; 91 } 92 93 // Shrink back down to the exact size. 94 dst->Resize(dst_offset); 95 96 return dst.release(); 97 } 98 99 template <typename AddressType> 100 void ElfInterface::InitHeadersWithTemplate() { 101 if (eh_frame_offset_ != 0) { 102 eh_frame_.reset(new DwarfEhFrame<AddressType>(memory_)); 103 if (!eh_frame_->Init(eh_frame_offset_, eh_frame_size_)) { 104 eh_frame_.reset(nullptr); 105 eh_frame_offset_ = 0; 106 eh_frame_size_ = static_cast<uint64_t>(-1); 107 } 108 } 109 110 if (debug_frame_offset_ != 0) { 111 debug_frame_.reset(new DwarfDebugFrame<AddressType>(memory_)); 112 if (!debug_frame_->Init(debug_frame_offset_, debug_frame_size_)) { 113 debug_frame_.reset(nullptr); 114 debug_frame_offset_ = 0; 115 debug_frame_size_ = static_cast<uint64_t>(-1); 116 } 117 } 118 } 119 120 template <typename EhdrType, typename PhdrType, typename ShdrType> 121 bool ElfInterface::ReadAllHeaders() { 122 EhdrType ehdr; 123 if (!memory_->Read(0, &ehdr, sizeof(ehdr))) { 124 return false; 125 } 126 127 if (!ReadProgramHeaders<EhdrType, PhdrType>(ehdr)) { 128 return false; 129 } 130 131 // We could still potentially unwind without the section header 132 // information, so ignore any errors. 133 if (!ReadSectionHeaders<EhdrType, ShdrType>(ehdr)) { 134 log(0, "Malformed section header found, ignoring..."); 135 } 136 return true; 137 } 138 139 template <typename EhdrType, typename PhdrType> 140 bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr) { 141 uint64_t offset = ehdr.e_phoff; 142 for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) { 143 PhdrType phdr; 144 if (!memory_->ReadField(offset, &phdr, &phdr.p_type, sizeof(phdr.p_type))) { 145 return false; 146 } 147 148 if (HandleType(offset, phdr.p_type)) { 149 continue; 150 } 151 152 switch (phdr.p_type) { 153 case PT_LOAD: 154 { 155 // Get the flags first, if this isn't an executable header, ignore it. 156 if (!memory_->ReadField(offset, &phdr, &phdr.p_flags, sizeof(phdr.p_flags))) { 157 return false; 158 } 159 if ((phdr.p_flags & PF_X) == 0) { 160 continue; 161 } 162 163 if (!memory_->ReadField(offset, &phdr, &phdr.p_vaddr, sizeof(phdr.p_vaddr))) { 164 return false; 165 } 166 if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) { 167 return false; 168 } 169 if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) { 170 return false; 171 } 172 pt_loads_[phdr.p_offset] = LoadInfo{phdr.p_offset, phdr.p_vaddr, 173 static_cast<size_t>(phdr.p_memsz)}; 174 if (phdr.p_offset == 0) { 175 load_bias_ = phdr.p_vaddr; 176 } 177 break; 178 } 179 180 case PT_GNU_EH_FRAME: 181 if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) { 182 return false; 183 } 184 eh_frame_offset_ = phdr.p_offset; 185 if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) { 186 return false; 187 } 188 eh_frame_size_ = phdr.p_memsz; 189 break; 190 191 case PT_DYNAMIC: 192 if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) { 193 return false; 194 } 195 dynamic_offset_ = phdr.p_offset; 196 if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) { 197 return false; 198 } 199 dynamic_size_ = phdr.p_memsz; 200 break; 201 } 202 } 203 return true; 204 } 205 206 template <typename EhdrType, typename ShdrType> 207 bool ElfInterface::ReadSectionHeaders(const EhdrType& ehdr) { 208 uint64_t offset = ehdr.e_shoff; 209 uint64_t sec_offset = 0; 210 uint64_t sec_size = 0; 211 212 // Get the location of the section header names. 213 // If something is malformed in the header table data, we aren't going 214 // to terminate, we'll simply ignore this part. 215 ShdrType shdr; 216 if (ehdr.e_shstrndx < ehdr.e_shnum) { 217 uint64_t sh_offset = offset + ehdr.e_shstrndx * ehdr.e_shentsize; 218 if (memory_->ReadField(sh_offset, &shdr, &shdr.sh_offset, sizeof(shdr.sh_offset)) && 219 memory_->ReadField(sh_offset, &shdr, &shdr.sh_size, sizeof(shdr.sh_size))) { 220 sec_offset = shdr.sh_offset; 221 sec_size = shdr.sh_size; 222 } 223 } 224 225 // Skip the first header, it's always going to be NULL. 226 offset += ehdr.e_shentsize; 227 for (size_t i = 1; i < ehdr.e_shnum; i++, offset += ehdr.e_shentsize) { 228 if (!memory_->ReadField(offset, &shdr, &shdr.sh_type, sizeof(shdr.sh_type))) { 229 return false; 230 } 231 232 if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) { 233 if (!memory_->Read(offset, &shdr, sizeof(shdr))) { 234 return false; 235 } 236 // Need to go get the information about the section that contains 237 // the string terminated names. 238 ShdrType str_shdr; 239 if (shdr.sh_link >= ehdr.e_shnum) { 240 return false; 241 } 242 uint64_t str_offset = ehdr.e_shoff + shdr.sh_link * ehdr.e_shentsize; 243 if (!memory_->ReadField(str_offset, &str_shdr, &str_shdr.sh_type, sizeof(str_shdr.sh_type))) { 244 return false; 245 } 246 if (str_shdr.sh_type != SHT_STRTAB) { 247 return false; 248 } 249 if (!memory_->ReadField(str_offset, &str_shdr, &str_shdr.sh_offset, 250 sizeof(str_shdr.sh_offset))) { 251 return false; 252 } 253 if (!memory_->ReadField(str_offset, &str_shdr, &str_shdr.sh_size, sizeof(str_shdr.sh_size))) { 254 return false; 255 } 256 symbols_.push_back(new Symbols(shdr.sh_offset, shdr.sh_size, shdr.sh_entsize, 257 str_shdr.sh_offset, str_shdr.sh_size)); 258 } else if (shdr.sh_type == SHT_PROGBITS && sec_size != 0) { 259 // Look for the .debug_frame and .gnu_debugdata. 260 if (!memory_->ReadField(offset, &shdr, &shdr.sh_name, sizeof(shdr.sh_name))) { 261 return false; 262 } 263 if (shdr.sh_name < sec_size) { 264 std::string name; 265 if (memory_->ReadString(sec_offset + shdr.sh_name, &name)) { 266 uint64_t* offset_ptr = nullptr; 267 uint64_t* size_ptr = nullptr; 268 if (name == ".debug_frame") { 269 offset_ptr = &debug_frame_offset_; 270 size_ptr = &debug_frame_size_; 271 } else if (name == ".gnu_debugdata") { 272 offset_ptr = &gnu_debugdata_offset_; 273 size_ptr = &gnu_debugdata_size_; 274 } 275 if (offset_ptr != nullptr && 276 memory_->ReadField(offset, &shdr, &shdr.sh_offset, sizeof(shdr.sh_offset)) && 277 memory_->ReadField(offset, &shdr, &shdr.sh_size, sizeof(shdr.sh_size))) { 278 *offset_ptr = shdr.sh_offset; 279 *size_ptr = shdr.sh_size; 280 } 281 } 282 } 283 } 284 } 285 return true; 286 } 287 288 template <typename DynType> 289 bool ElfInterface::GetSonameWithTemplate(std::string* soname) { 290 if (soname_type_ == SONAME_INVALID) { 291 return false; 292 } 293 if (soname_type_ == SONAME_VALID) { 294 *soname = soname_; 295 return true; 296 } 297 298 soname_type_ = SONAME_INVALID; 299 300 uint64_t soname_offset = 0; 301 uint64_t strtab_offset = 0; 302 uint64_t strtab_size = 0; 303 304 // Find the soname location from the dynamic headers section. 305 DynType dyn; 306 uint64_t offset = dynamic_offset_; 307 uint64_t max_offset = offset + dynamic_size_; 308 for (uint64_t offset = dynamic_offset_; offset < max_offset; offset += sizeof(DynType)) { 309 if (!memory_->Read(offset, &dyn, sizeof(dyn))) { 310 return false; 311 } 312 313 if (dyn.d_tag == DT_STRTAB) { 314 strtab_offset = dyn.d_un.d_ptr; 315 } else if (dyn.d_tag == DT_STRSZ) { 316 strtab_size = dyn.d_un.d_val; 317 } else if (dyn.d_tag == DT_SONAME) { 318 soname_offset = dyn.d_un.d_val; 319 } else if (dyn.d_tag == DT_NULL) { 320 break; 321 } 322 } 323 324 soname_offset += strtab_offset; 325 if (soname_offset >= strtab_offset + strtab_size) { 326 return false; 327 } 328 if (!memory_->ReadString(soname_offset, &soname_)) { 329 return false; 330 } 331 soname_type_ = SONAME_VALID; 332 *soname = soname_; 333 return true; 334 } 335 336 template <typename SymType> 337 bool ElfInterface::GetFunctionNameWithTemplate(uint64_t addr, std::string* name, 338 uint64_t* func_offset) { 339 if (symbols_.empty()) { 340 return false; 341 } 342 343 for (const auto symbol : symbols_) { 344 if (symbol->GetName<SymType>(addr, load_bias_, memory_, name, func_offset)) { 345 return true; 346 } 347 } 348 return false; 349 } 350 351 bool ElfInterface::Step(uint64_t pc, Regs* regs, Memory* process_memory) { 352 // Need to subtract off the load_bias to get the correct pc. 353 if (pc < load_bias_) { 354 return false; 355 } 356 pc -= load_bias_; 357 358 // Try the eh_frame first. 359 DwarfSection* eh_frame = eh_frame_.get(); 360 if (eh_frame != nullptr && eh_frame->Step(pc, regs, process_memory)) { 361 return true; 362 } 363 364 // Try the debug_frame next. 365 DwarfSection* debug_frame = debug_frame_.get(); 366 if (debug_frame != nullptr && debug_frame->Step(pc, regs, process_memory)) { 367 return true; 368 } 369 370 return false; 371 } 372 373 // Instantiate all of the needed template functions. 374 template void ElfInterface::InitHeadersWithTemplate<uint32_t>(); 375 template void ElfInterface::InitHeadersWithTemplate<uint64_t>(); 376 377 template bool ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(); 378 template bool ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(); 379 380 template bool ElfInterface::ReadProgramHeaders<Elf32_Ehdr, Elf32_Phdr>(const Elf32_Ehdr&); 381 template bool ElfInterface::ReadProgramHeaders<Elf64_Ehdr, Elf64_Phdr>(const Elf64_Ehdr&); 382 383 template bool ElfInterface::ReadSectionHeaders<Elf32_Ehdr, Elf32_Shdr>(const Elf32_Ehdr&); 384 template bool ElfInterface::ReadSectionHeaders<Elf64_Ehdr, Elf64_Shdr>(const Elf64_Ehdr&); 385 386 template bool ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(std::string*); 387 template bool ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(std::string*); 388 389 template bool ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(uint64_t, std::string*, 390 uint64_t*); 391 template bool ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(uint64_t, std::string*, 392 uint64_t*); 393 394 } // namespace unwindstack 395