diff options
author | Christopher Ferris <cferris@google.com> | 2019-03-14 15:40:59 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2019-03-14 15:40:59 +0000 |
commit | 4886a5bd5942275c20fa95df3ccb03e70a97328c (patch) | |
tree | 8c40e397a05578712906cb0e546a77d9799f0dd1 /libunwindstack/MapInfo.cpp | |
parent | ff3c13f52f1d223a4aa2904234867e6199643766 (diff) | |
parent | 02a6c448c32c37aae834bc25e92db97bfac32524 (diff) |
Merge "Add support for displaying soname in an apk."
Diffstat (limited to 'libunwindstack/MapInfo.cpp')
-rw-r--r-- | libunwindstack/MapInfo.cpp | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp index a38236c60..28373b27f 100644 --- a/libunwindstack/MapInfo.cpp +++ b/libunwindstack/MapInfo.cpp @@ -188,43 +188,56 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { } Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum expected_arch) { - // Make sure no other thread is trying to add the elf to this map. - std::lock_guard<std::mutex> guard(mutex_); - - if (elf.get() != nullptr) { - return elf.get(); - } + { + // Make sure no other thread is trying to add the elf to this map. + std::lock_guard<std::mutex> guard(mutex_); - bool locked = false; - if (Elf::CachingEnabled() && !name.empty()) { - Elf::CacheLock(); - locked = true; - if (Elf::CacheGet(this)) { - Elf::CacheUnlock(); + if (elf.get() != nullptr) { return elf.get(); } - } - Memory* memory = CreateMemory(process_memory); - if (locked) { - if (Elf::CacheAfterCreateMemory(this)) { - delete memory; + bool locked = false; + if (Elf::CachingEnabled() && !name.empty()) { + Elf::CacheLock(); + locked = true; + if (Elf::CacheGet(this)) { + Elf::CacheUnlock(); + return elf.get(); + } + } + + Memory* memory = CreateMemory(process_memory); + if (locked) { + if (Elf::CacheAfterCreateMemory(this)) { + delete memory; + Elf::CacheUnlock(); + return elf.get(); + } + } + elf.reset(new Elf(memory)); + // If the init fails, keep the elf around as an invalid object so we + // don't try to reinit the object. + elf->Init(); + if (elf->valid() && expected_arch != elf->arch()) { + // Make the elf invalid, mismatch between arch and expected arch. + elf->Invalidate(); + } + + if (locked) { + Elf::CacheAdd(this); Elf::CacheUnlock(); - return elf.get(); } } - elf.reset(new Elf(memory)); - // If the init fails, keep the elf around as an invalid object so we - // don't try to reinit the object. - elf->Init(); - if (elf->valid() && expected_arch != elf->arch()) { - // Make the elf invalid, mismatch between arch and expected arch. - elf->Invalidate(); - } - if (locked) { - Elf::CacheAdd(this); - Elf::CacheUnlock(); + // If there is a read-only map then a read-execute map that represents the + // same elf object, make sure the previous map is using the same elf + // object if it hasn't already been set. + if (prev_map != nullptr && elf_start_offset != offset && prev_map->offset == elf_start_offset && + prev_map->name == name) { + std::lock_guard<std::mutex> guard(prev_map->mutex_); + if (prev_map->elf.get() == nullptr) { + prev_map->elf = elf; + } } return elf.get(); } |