Loading libbacktrace/UnwindStack.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, back_frame->map.name = frame->map_name; back_frame->map.start = frame->map_start; back_frame->map.end = frame->map_end; back_frame->map.offset = frame->map_offset; back_frame->map.offset = frame->map_elf_start_offset; back_frame->map.load_bias = frame->map_load_bias; back_frame->map.flags = frame->map_flags; } Loading libunwindstack/MapInfo.cpp +37 −48 Original line number Diff line number Diff line Loading @@ -32,34 +32,28 @@ namespace unwindstack { bool MapInfo::InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory) { // One last attempt, see if the previous map is read-only with the // same name and stretches across this map. for (auto iter = maps_->begin(); iter != maps_->end(); ++iter) { if (*iter == this) { if (iter == maps_->begin()) { return false; } --iter; MapInfo* prev_map = *iter; // Make sure this is a read-only map. if (prev_map->flags != PROT_READ) { if (prev_map == nullptr || prev_map->flags != PROT_READ) { return false; } uint64_t map_size = end - prev_map->end; if (!memory->Init(name, prev_map->offset, map_size)) { return false; } uint64_t max_size; if (!Elf::GetInfo(memory, &max_size) || max_size < map_size) { return false; } if (!memory->Init(name, prev_map->offset, max_size)) { return false; } elf_offset = offset - prev_map->offset; elf_start_offset = prev_map->offset; return true; } } return false; } Memory* MapInfo::GetFileMemory() { std::unique_ptr<MemoryFileAtOffset> memory(new MemoryFileAtOffset); Loading Loading @@ -91,14 +85,13 @@ Memory* MapInfo::GetFileMemory() { // Check if the start of this map is an embedded elf. uint64_t max_size = 0; uint64_t file_offset = offset; if (Elf::GetInfo(memory.get(), &max_size)) { if (max_size > map_size) { if (memory->Init(name, file_offset, max_size)) { if (memory->Init(name, offset, max_size)) { return memory.release(); } // Try to reinit using the default map_size. if (memory->Init(name, file_offset, map_size)) { if (memory->Init(name, offset, map_size)) { return memory.release(); } return nullptr; Loading @@ -109,6 +102,13 @@ Memory* MapInfo::GetFileMemory() { // No elf at offset, try to init as if the whole file is an elf. if (memory->Init(name, 0) && Elf::IsValidElf(memory.get())) { elf_offset = offset; // Need to check how to set the elf start offset. If this map is not // the r-x map of a r-- map, then use the real offset value. Otherwise, // use 0. if (prev_map == nullptr || prev_map->offset != 0 || prev_map->flags != PROT_READ || prev_map->name != name) { elf_start_offset = offset; } return memory.release(); } Loading Loading @@ -156,35 +156,24 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { return memory.release(); } if (name.empty() || maps_ == nullptr) { return nullptr; } // Find the read-only map by looking at the previous map. The linker // doesn't guarantee that this invariant will always be true. However, // if that changes, there is likely something else that will change and // break something. MapInfo* ro_map_info = nullptr; for (auto iter = maps_->begin(); iter != maps_->end(); ++iter) { if (*iter == this) { if (iter != maps_->begin()) { --iter; ro_map_info = *iter; } break; } } if (ro_map_info == nullptr || ro_map_info->name != name || ro_map_info->offset >= offset) { if (offset == 0 || name.empty() || prev_map == nullptr || prev_map->name != name || prev_map->offset >= offset) { return nullptr; } // Make sure that relative pc values are corrected properly. elf_offset = offset - ro_map_info->offset; elf_offset = offset - prev_map->offset; // Use this as the elf start offset, otherwise, you always get offsets into // the r-x section, which is not quite the right information. elf_start_offset = prev_map->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, prev_map->start, prev_map->end - prev_map->start, 0)); ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset)); return ranges; Loading libunwindstack/Maps.cpp +13 −3 Original line number Diff line number Diff line Loading @@ -67,13 +67,15 @@ 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(this, start, end, pgoff, flags, name)); maps_.push_back( new MapInfo(maps_.empty() ? nullptr : maps_.back(), 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(this, start, end, offset, flags, name); MapInfo* map_info = new MapInfo(maps_.empty() ? nullptr : maps_.back(), start, end, offset, flags, name); map_info->load_bias = load_bias; maps_.push_back(map_info); } Loading @@ -81,6 +83,13 @@ void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, void Maps::Sort() { std::sort(maps_.begin(), maps_.end(), [](const MapInfo* a, const MapInfo* b) { return a->start < b->start; }); // Set the prev_map values on the info objects. MapInfo* prev_map = nullptr; for (MapInfo* map_info : maps_) { map_info->prev_map = prev_map; prev_map = map_info; } } Maps::~Maps() { Loading @@ -98,7 +107,8 @@ 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(this, start, end, pgoff, flags, name)); maps_.push_back( new MapInfo(maps_.empty() ? nullptr : maps_.back(), start, end, pgoff, flags, name)); }); } Loading libunwindstack/Unwinder.cpp +9 −6 Original line number Diff line number Diff line Loading @@ -59,7 +59,8 @@ void Unwinder::FillInDexFrame() { if (info != nullptr) { frame->map_start = info->start; frame->map_end = info->end; frame->map_offset = info->offset; frame->map_elf_start_offset = info->elf_start_offset; frame->map_exact_offset = info->offset; frame->map_load_bias = info->load_bias; frame->map_flags = info->flags; if (resolve_names_) { Loading Loading @@ -102,7 +103,8 @@ void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_ if (resolve_names_) { frame->map_name = map_info->name; } frame->map_offset = map_info->offset; frame->map_elf_start_offset = map_info->elf_start_offset; frame->map_exact_offset = map_info->offset; frame->map_start = map_info->start; frame->map_end = map_info->end; frame->map_flags = map_info->flags; Loading Loading @@ -290,10 +292,6 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) { data += android::base::StringPrintf(" #%02zu pc %016" PRIx64, frame.num, frame.rel_pc); } if (frame.map_offset != 0) { data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", frame.map_offset); } if (frame.map_start == frame.map_end) { // No valid map associated with this frame. data += " <unknown>"; Loading @@ -302,6 +300,11 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) { } else { data += android::base::StringPrintf(" <anonymous:%" PRIx64 ">", frame.map_start); } if (frame.map_elf_start_offset != 0) { data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", frame.map_elf_start_offset); } if (!frame.function_name.empty()) { data += " (" + frame.function_name; if (frame.function_offset != 0) { Loading libunwindstack/include/unwindstack/MapInfo.h +14 −17 Original line number Diff line number Diff line Loading @@ -25,38 +25,31 @@ #include <string> #include <unwindstack/Elf.h> #include <unwindstack/Memory.h> namespace unwindstack { // Forward declarations. class Maps; class Memory; struct MapInfo { MapInfo(Maps* maps) : maps_(maps) {} MapInfo(Maps* maps, uint64_t start, uint64_t end) : maps_(maps), start(start), end(end) {} MapInfo(Maps* maps, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, MapInfo(MapInfo* map_info, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const char* name) : maps_(maps), start(start), : start(start), end(end), offset(offset), flags(flags), name(name), prev_map(map_info), load_bias(static_cast<uint64_t>(-1)) {} MapInfo(Maps* maps, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, MapInfo(MapInfo* map_info, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name) : maps_(maps), start(start), : start(start), end(end), offset(offset), flags(flags), name(name), prev_map(map_info), load_bias(static_cast<uint64_t>(-1)) {} ~MapInfo() = default; Maps* maps_ = nullptr; uint64_t start = 0; uint64_t end = 0; uint64_t offset = 0; Loading @@ -64,10 +57,14 @@ struct MapInfo { std::string name; std::shared_ptr<Elf> elf; // This value is only non-zero if the offset is non-zero but there is // no elf signature found at that offset. This indicates that the // entire file is represented by the Memory object returned by CreateMemory, // instead of a portion of the file. // no elf signature found at that offset. uint64_t elf_offset = 0; // This value is the offset from the map in memory that is the start // of the elf. This is not equal to offset when the linker splits // shared libraries into a read-only and read-execute map. uint64_t elf_start_offset = 0; MapInfo* prev_map = nullptr; std::atomic_uint64_t load_bias; Loading Loading
libbacktrace/UnwindStack.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, back_frame->map.name = frame->map_name; back_frame->map.start = frame->map_start; back_frame->map.end = frame->map_end; back_frame->map.offset = frame->map_offset; back_frame->map.offset = frame->map_elf_start_offset; back_frame->map.load_bias = frame->map_load_bias; back_frame->map.flags = frame->map_flags; } Loading
libunwindstack/MapInfo.cpp +37 −48 Original line number Diff line number Diff line Loading @@ -32,34 +32,28 @@ namespace unwindstack { bool MapInfo::InitFileMemoryFromPreviousReadOnlyMap(MemoryFileAtOffset* memory) { // One last attempt, see if the previous map is read-only with the // same name and stretches across this map. for (auto iter = maps_->begin(); iter != maps_->end(); ++iter) { if (*iter == this) { if (iter == maps_->begin()) { return false; } --iter; MapInfo* prev_map = *iter; // Make sure this is a read-only map. if (prev_map->flags != PROT_READ) { if (prev_map == nullptr || prev_map->flags != PROT_READ) { return false; } uint64_t map_size = end - prev_map->end; if (!memory->Init(name, prev_map->offset, map_size)) { return false; } uint64_t max_size; if (!Elf::GetInfo(memory, &max_size) || max_size < map_size) { return false; } if (!memory->Init(name, prev_map->offset, max_size)) { return false; } elf_offset = offset - prev_map->offset; elf_start_offset = prev_map->offset; return true; } } return false; } Memory* MapInfo::GetFileMemory() { std::unique_ptr<MemoryFileAtOffset> memory(new MemoryFileAtOffset); Loading Loading @@ -91,14 +85,13 @@ Memory* MapInfo::GetFileMemory() { // Check if the start of this map is an embedded elf. uint64_t max_size = 0; uint64_t file_offset = offset; if (Elf::GetInfo(memory.get(), &max_size)) { if (max_size > map_size) { if (memory->Init(name, file_offset, max_size)) { if (memory->Init(name, offset, max_size)) { return memory.release(); } // Try to reinit using the default map_size. if (memory->Init(name, file_offset, map_size)) { if (memory->Init(name, offset, map_size)) { return memory.release(); } return nullptr; Loading @@ -109,6 +102,13 @@ Memory* MapInfo::GetFileMemory() { // No elf at offset, try to init as if the whole file is an elf. if (memory->Init(name, 0) && Elf::IsValidElf(memory.get())) { elf_offset = offset; // Need to check how to set the elf start offset. If this map is not // the r-x map of a r-- map, then use the real offset value. Otherwise, // use 0. if (prev_map == nullptr || prev_map->offset != 0 || prev_map->flags != PROT_READ || prev_map->name != name) { elf_start_offset = offset; } return memory.release(); } Loading Loading @@ -156,35 +156,24 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) { return memory.release(); } if (name.empty() || maps_ == nullptr) { return nullptr; } // Find the read-only map by looking at the previous map. The linker // doesn't guarantee that this invariant will always be true. However, // if that changes, there is likely something else that will change and // break something. MapInfo* ro_map_info = nullptr; for (auto iter = maps_->begin(); iter != maps_->end(); ++iter) { if (*iter == this) { if (iter != maps_->begin()) { --iter; ro_map_info = *iter; } break; } } if (ro_map_info == nullptr || ro_map_info->name != name || ro_map_info->offset >= offset) { if (offset == 0 || name.empty() || prev_map == nullptr || prev_map->name != name || prev_map->offset >= offset) { return nullptr; } // Make sure that relative pc values are corrected properly. elf_offset = offset - ro_map_info->offset; elf_offset = offset - prev_map->offset; // Use this as the elf start offset, otherwise, you always get offsets into // the r-x section, which is not quite the right information. elf_start_offset = prev_map->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, prev_map->start, prev_map->end - prev_map->start, 0)); ranges->Insert(new MemoryRange(process_memory, start, end - start, elf_offset)); return ranges; Loading
libunwindstack/Maps.cpp +13 −3 Original line number Diff line number Diff line Loading @@ -67,13 +67,15 @@ 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(this, start, end, pgoff, flags, name)); maps_.push_back( new MapInfo(maps_.empty() ? nullptr : maps_.back(), 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(this, start, end, offset, flags, name); MapInfo* map_info = new MapInfo(maps_.empty() ? nullptr : maps_.back(), start, end, offset, flags, name); map_info->load_bias = load_bias; maps_.push_back(map_info); } Loading @@ -81,6 +83,13 @@ void Maps::Add(uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, void Maps::Sort() { std::sort(maps_.begin(), maps_.end(), [](const MapInfo* a, const MapInfo* b) { return a->start < b->start; }); // Set the prev_map values on the info objects. MapInfo* prev_map = nullptr; for (MapInfo* map_info : maps_) { map_info->prev_map = prev_map; prev_map = map_info; } } Maps::~Maps() { Loading @@ -98,7 +107,8 @@ 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(this, start, end, pgoff, flags, name)); maps_.push_back( new MapInfo(maps_.empty() ? nullptr : maps_.back(), start, end, pgoff, flags, name)); }); } Loading
libunwindstack/Unwinder.cpp +9 −6 Original line number Diff line number Diff line Loading @@ -59,7 +59,8 @@ void Unwinder::FillInDexFrame() { if (info != nullptr) { frame->map_start = info->start; frame->map_end = info->end; frame->map_offset = info->offset; frame->map_elf_start_offset = info->elf_start_offset; frame->map_exact_offset = info->offset; frame->map_load_bias = info->load_bias; frame->map_flags = info->flags; if (resolve_names_) { Loading Loading @@ -102,7 +103,8 @@ void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_ if (resolve_names_) { frame->map_name = map_info->name; } frame->map_offset = map_info->offset; frame->map_elf_start_offset = map_info->elf_start_offset; frame->map_exact_offset = map_info->offset; frame->map_start = map_info->start; frame->map_end = map_info->end; frame->map_flags = map_info->flags; Loading Loading @@ -290,10 +292,6 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) { data += android::base::StringPrintf(" #%02zu pc %016" PRIx64, frame.num, frame.rel_pc); } if (frame.map_offset != 0) { data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", frame.map_offset); } if (frame.map_start == frame.map_end) { // No valid map associated with this frame. data += " <unknown>"; Loading @@ -302,6 +300,11 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) { } else { data += android::base::StringPrintf(" <anonymous:%" PRIx64 ">", frame.map_start); } if (frame.map_elf_start_offset != 0) { data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", frame.map_elf_start_offset); } if (!frame.function_name.empty()) { data += " (" + frame.function_name; if (frame.function_offset != 0) { Loading
libunwindstack/include/unwindstack/MapInfo.h +14 −17 Original line number Diff line number Diff line Loading @@ -25,38 +25,31 @@ #include <string> #include <unwindstack/Elf.h> #include <unwindstack/Memory.h> namespace unwindstack { // Forward declarations. class Maps; class Memory; struct MapInfo { MapInfo(Maps* maps) : maps_(maps) {} MapInfo(Maps* maps, uint64_t start, uint64_t end) : maps_(maps), start(start), end(end) {} MapInfo(Maps* maps, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, MapInfo(MapInfo* map_info, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const char* name) : maps_(maps), start(start), : start(start), end(end), offset(offset), flags(flags), name(name), prev_map(map_info), load_bias(static_cast<uint64_t>(-1)) {} MapInfo(Maps* maps, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, MapInfo(MapInfo* map_info, uint64_t start, uint64_t end, uint64_t offset, uint64_t flags, const std::string& name) : maps_(maps), start(start), : start(start), end(end), offset(offset), flags(flags), name(name), prev_map(map_info), load_bias(static_cast<uint64_t>(-1)) {} ~MapInfo() = default; Maps* maps_ = nullptr; uint64_t start = 0; uint64_t end = 0; uint64_t offset = 0; Loading @@ -64,10 +57,14 @@ struct MapInfo { std::string name; std::shared_ptr<Elf> elf; // This value is only non-zero if the offset is non-zero but there is // no elf signature found at that offset. This indicates that the // entire file is represented by the Memory object returned by CreateMemory, // instead of a portion of the file. // no elf signature found at that offset. uint64_t elf_offset = 0; // This value is the offset from the map in memory that is the start // of the elf. This is not equal to offset when the linker splits // shared libraries into a read-only and read-execute map. uint64_t elf_start_offset = 0; MapInfo* prev_map = nullptr; std::atomic_uint64_t load_bias; Loading