summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/ElfInterface.cpp')
-rw-r--r--libunwindstack/ElfInterface.cpp24
1 files changed, 21 insertions, 3 deletions
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 20cc1b06c..d5d158f82 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -32,6 +32,7 @@
32 32
33#include "DwarfDebugFrame.h" 33#include "DwarfDebugFrame.h"
34#include "DwarfEhFrame.h" 34#include "DwarfEhFrame.h"
35#include "DwarfEhFrameWithHdr.h"
35#include "Symbols.h" 36#include "Symbols.h"
36 37
37namespace unwindstack { 38namespace unwindstack {
@@ -98,7 +99,17 @@ Memory* ElfInterface::CreateGnuDebugdataMemory() {
98 99
99template <typename AddressType> 100template <typename AddressType>
100void ElfInterface::InitHeadersWithTemplate() { 101void ElfInterface::InitHeadersWithTemplate() {
101 if (eh_frame_offset_ != 0) { 102 if (eh_frame_hdr_offset_ != 0) {
103 eh_frame_.reset(new DwarfEhFrameWithHdr<AddressType>(memory_));
104 if (!eh_frame_->Init(eh_frame_hdr_offset_, eh_frame_hdr_size_)) {
105 // Even if the eh_frame_offset_ is non-zero, do not bother
106 // trying to read that since something has gone wrong.
107 eh_frame_.reset(nullptr);
108 eh_frame_hdr_offset_ = 0;
109 eh_frame_hdr_size_ = static_cast<uint64_t>(-1);
110 }
111 } else if (eh_frame_offset_ != 0) {
112 // If there is a eh_frame section without a eh_frame_hdr section.
102 eh_frame_.reset(new DwarfEhFrame<AddressType>(memory_)); 113 eh_frame_.reset(new DwarfEhFrame<AddressType>(memory_));
103 if (!eh_frame_->Init(eh_frame_offset_, eh_frame_size_)) { 114 if (!eh_frame_->Init(eh_frame_offset_, eh_frame_size_)) {
104 eh_frame_.reset(nullptr); 115 eh_frame_.reset(nullptr);
@@ -181,11 +192,12 @@ bool ElfInterface::ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias)
181 if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) { 192 if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) {
182 return false; 193 return false;
183 } 194 }
184 eh_frame_offset_ = phdr.p_offset; 195 // This is really the pointer to the .eh_frame_hdr section.
196 eh_frame_hdr_offset_ = phdr.p_offset;
185 if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) { 197 if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
186 return false; 198 return false;
187 } 199 }
188 eh_frame_size_ = phdr.p_memsz; 200 eh_frame_hdr_size_ = phdr.p_memsz;
189 break; 201 break;
190 202
191 case PT_DYNAMIC: 203 case PT_DYNAMIC:
@@ -271,6 +283,12 @@ bool ElfInterface::ReadSectionHeaders(const EhdrType& ehdr) {
271 } else if (name == ".gnu_debugdata") { 283 } else if (name == ".gnu_debugdata") {
272 offset_ptr = &gnu_debugdata_offset_; 284 offset_ptr = &gnu_debugdata_offset_;
273 size_ptr = &gnu_debugdata_size_; 285 size_ptr = &gnu_debugdata_size_;
286 } else if (name == ".eh_frame") {
287 offset_ptr = &eh_frame_offset_;
288 size_ptr = &eh_frame_size_;
289 } else if (eh_frame_hdr_offset_ == 0 && name == ".eh_frame_hdr") {
290 offset_ptr = &eh_frame_hdr_offset_;
291 size_ptr = &eh_frame_hdr_size_;
274 } 292 }
275 if (offset_ptr != nullptr && 293 if (offset_ptr != nullptr &&
276 memory_->ReadField(offset, &shdr, &shdr.sh_offset, sizeof(shdr.sh_offset)) && 294 memory_->ReadField(offset, &shdr, &shdr.sh_offset, sizeof(shdr.sh_offset)) &&