Loading libbacktrace/Android.bp +0 −4 Original line number Diff line number Diff line Loading @@ -116,10 +116,6 @@ cc_test_library { target: { linux_glibc: { // The host uses rosegment, which isn't supported yet. ldflags: [ "-Wl,--no-rosegment", ], // This forces the creation of eh_frame with unwind information // for host. cflags: [ Loading libunwindstack/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,7 @@ cc_test { "tests/JitDebugTest.cpp", "tests/LocalUnwinderTest.cpp", "tests/LogFake.cpp", "tests/MapInfoCreateMemoryTest.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", "tests/MapsTest.cpp", Loading @@ -188,6 +189,7 @@ cc_test { "tests/MemoryOfflineBufferTest.cpp", "tests/MemoryOfflineTest.cpp", "tests/MemoryRangeTest.cpp", "tests/MemoryRangesTest.cpp", "tests/MemoryRemoteTest.cpp", "tests/MemoryTest.cpp", "tests/RegsInfoTest.cpp", Loading libunwindstack/MapInfo.cpp +48 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,54 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { if (!(flags & PROT_READ)) { return nullptr; } return new MemoryRange(process_memory, start, end - start, 0); // Need to verify that this elf is valid. It's possible that // only part of the elf file to be mapped into memory is in the executable // map. In this case, there will be another read-only map that includes the // first part of the elf file. This is done if the linker rosegment // option is used. std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0)); bool valid; uint64_t max_size; Elf::GetInfo(memory.get(), &valid, &max_size); if (valid) { // Valid elf, we are done. return memory.release(); } if (name.empty() || maps_ == nullptr) { return nullptr; } // Find the read-only map that has the same name and has an offset closest // to the current offset but less than the offset of the current map. // For shared libraries, there should be a r-x map that has a non-zero // offset and then a r-- map that has a zero offset. // For shared libraries loaded from an apk, there should be a r-x map that // has a non-zero offset and then a r-- map that has a non-zero offset less // than the offset from the r-x map. uint64_t closest_offset = 0; MapInfo* ro_map_info = nullptr; for (auto map_info : *maps_) { if (map_info->flags == PROT_READ && map_info->name == name && map_info->offset < offset && map_info->offset >= closest_offset) { ro_map_info = map_info; closest_offset = ro_map_info->offset; } } if (ro_map_info != nullptr) { // Make sure that relative pc values are corrected properly. elf_offset = offset - closest_offset; MemoryRanges* ranges = new MemoryRanges; ranges->Insert(new MemoryRange(process_memory, ro_map_info->start, ro_map_info->end - ro_map_info->start, 0)); ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset)); return ranges; } return nullptr; } Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) { Loading libunwindstack/Maps.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -66,13 +66,13 @@ bool Maps::Parse() { if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) { flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP; } maps_.push_back(new MapInfo(start, end, pgoff, flags, name)); maps_.push_back(new MapInfo(this, start, end, pgoff, flags, name)); }); } void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name, uint64_t load_bias) { MapInfo* map_info = new MapInfo(start, end, offset, flags, name); MapInfo* map_info = new MapInfo(this, start, end, offset, flags, name); map_info->load_bias = load_bias; maps_.push_back(map_info); } Loading @@ -97,7 +97,7 @@ bool BufferMaps::Parse() { if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) { flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP; } maps_.push_back(new MapInfo(start, end, pgoff, flags, name)); maps_.push_back(new MapInfo(this, start, end, pgoff, flags, name)); }); } Loading libunwindstack/Memory.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -316,6 +316,18 @@ size_t MemoryRange::Read(uint64_t addr, void* dst, size_t size) { return memory_->Read(read_addr, dst, read_length); } void MemoryRanges::Insert(MemoryRange* memory) { maps_.emplace(memory->offset() + memory->length(), memory); } size_t MemoryRanges::Read(uint64_t addr, void* dst, size_t size) { auto entry = maps_.upper_bound(addr); if (entry != maps_.end()) { return entry->second->Read(addr, dst, size); } return 0; } bool MemoryOffline::Init(const std::string& file, uint64_t offset) { auto memory_file = std::make_shared<MemoryFileAtOffset>(); if (!memory_file->Init(file, offset)) { Loading Loading
libbacktrace/Android.bp +0 −4 Original line number Diff line number Diff line Loading @@ -116,10 +116,6 @@ cc_test_library { target: { linux_glibc: { // The host uses rosegment, which isn't supported yet. ldflags: [ "-Wl,--no-rosegment", ], // This forces the creation of eh_frame with unwind information // for host. cflags: [ Loading
libunwindstack/Android.bp +2 −0 Original line number Diff line number Diff line Loading @@ -178,6 +178,7 @@ cc_test { "tests/JitDebugTest.cpp", "tests/LocalUnwinderTest.cpp", "tests/LogFake.cpp", "tests/MapInfoCreateMemoryTest.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", "tests/MapsTest.cpp", Loading @@ -188,6 +189,7 @@ cc_test { "tests/MemoryOfflineBufferTest.cpp", "tests/MemoryOfflineTest.cpp", "tests/MemoryRangeTest.cpp", "tests/MemoryRangesTest.cpp", "tests/MemoryRemoteTest.cpp", "tests/MemoryTest.cpp", "tests/RegsInfoTest.cpp", Loading
libunwindstack/MapInfo.cpp +48 −1 Original line number Diff line number Diff line Loading @@ -102,7 +102,54 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { if (!(flags & PROT_READ)) { return nullptr; } return new MemoryRange(process_memory, start, end - start, 0); // Need to verify that this elf is valid. It's possible that // only part of the elf file to be mapped into memory is in the executable // map. In this case, there will be another read-only map that includes the // first part of the elf file. This is done if the linker rosegment // option is used. std::unique_ptr<MemoryRange> memory(new MemoryRange(process_memory, start, end - start, 0)); bool valid; uint64_t max_size; Elf::GetInfo(memory.get(), &valid, &max_size); if (valid) { // Valid elf, we are done. return memory.release(); } if (name.empty() || maps_ == nullptr) { return nullptr; } // Find the read-only map that has the same name and has an offset closest // to the current offset but less than the offset of the current map. // For shared libraries, there should be a r-x map that has a non-zero // offset and then a r-- map that has a zero offset. // For shared libraries loaded from an apk, there should be a r-x map that // has a non-zero offset and then a r-- map that has a non-zero offset less // than the offset from the r-x map. uint64_t closest_offset = 0; MapInfo* ro_map_info = nullptr; for (auto map_info : *maps_) { if (map_info->flags == PROT_READ && map_info->name == name && map_info->offset < offset && map_info->offset >= closest_offset) { ro_map_info = map_info; closest_offset = ro_map_info->offset; } } if (ro_map_info != nullptr) { // Make sure that relative pc values are corrected properly. elf_offset = offset - closest_offset; MemoryRanges* ranges = new MemoryRanges; ranges->Insert(new MemoryRange(process_memory, ro_map_info->start, ro_map_info->end - ro_map_info->start, 0)); ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset)); return ranges; } return nullptr; } Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) { Loading
libunwindstack/Maps.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -66,13 +66,13 @@ bool Maps::Parse() { if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) { flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP; } maps_.push_back(new MapInfo(start, end, pgoff, flags, name)); maps_.push_back(new MapInfo(this, start, end, pgoff, flags, name)); }); } void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name, uint64_t load_bias) { MapInfo* map_info = new MapInfo(start, end, offset, flags, name); MapInfo* map_info = new MapInfo(this, start, end, offset, flags, name); map_info->load_bias = load_bias; maps_.push_back(map_info); } Loading @@ -97,7 +97,7 @@ bool BufferMaps::Parse() { if (strncmp(name, "/dev/", 5) == 0 && strncmp(name + 5, "ashmem/", 7) != 0) { flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP; } maps_.push_back(new MapInfo(start, end, pgoff, flags, name)); maps_.push_back(new MapInfo(this, start, end, pgoff, flags, name)); }); } Loading
libunwindstack/Memory.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -316,6 +316,18 @@ size_t MemoryRange::Read(uint64_t addr, void* dst, size_t size) { return memory_->Read(read_addr, dst, read_length); } void MemoryRanges::Insert(MemoryRange* memory) { maps_.emplace(memory->offset() + memory->length(), memory); } size_t MemoryRanges::Read(uint64_t addr, void* dst, size_t size) { auto entry = maps_.upper_bound(addr); if (entry != maps_.end()) { return entry->second->Read(addr, dst, size); } return 0; } bool MemoryOffline::Init(const std::string& file, uint64_t offset) { auto memory_file = std::make_shared<MemoryFileAtOffset>(); if (!memory_file->Init(file, offset)) { Loading