Fix support finding global variables.
The code was not properly getting the variable addresses and using
the offset and address fields of the .data section.
Fix all of that, and update the tests.
Bug: 145162678
Test: Unit tests pass.
Test: ./art/test/run-test --dex2oat-jobs 4 --host --prebuild --compact-dex-level fast --jit --no-relocate --runtime-option -Xcheck:jni 137-cfi
Test: ./art/test/testrunner/testrunner.py -t 137 --host
Change-Id: Ic61c4487334fd2273cda9c56eb1a3b525a03edb7
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 5f95fa8..7676289 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -236,8 +236,12 @@
case PT_DYNAMIC:
dynamic_offset_ = phdr.p_offset;
- dynamic_vaddr_ = phdr.p_vaddr;
- dynamic_size_ = phdr.p_memsz;
+ dynamic_vaddr_start_ = phdr.p_vaddr;
+ if (__builtin_add_overflow(dynamic_vaddr_start_, phdr.p_memsz, &dynamic_vaddr_end_)) {
+ dynamic_offset_ = 0;
+ dynamic_vaddr_start_ = 0;
+ dynamic_vaddr_end_ = 0;
+ }
break;
default:
@@ -360,6 +364,14 @@
eh_frame_hdr_offset_ = shdr.sh_offset;
eh_frame_hdr_section_bias_ = static_cast<uint64_t>(shdr.sh_addr) - shdr.sh_offset;
eh_frame_hdr_size_ = shdr.sh_size;
+ } else if (name == ".data") {
+ data_offset_ = shdr.sh_offset;
+ data_vaddr_start_ = shdr.sh_addr;
+ if (__builtin_add_overflow(data_vaddr_start_, shdr.sh_size, &data_vaddr_end_)) {
+ data_offset_ = 0;
+ data_vaddr_start_ = 0;
+ data_vaddr_end_ = 0;
+ }
}
}
}
@@ -398,7 +410,7 @@
// Find the soname location from the dynamic headers section.
DynType dyn;
uint64_t offset = dynamic_offset_;
- uint64_t max_offset = offset + dynamic_size_;
+ uint64_t max_offset = offset + dynamic_vaddr_end_ - dynamic_vaddr_start_;
for (uint64_t offset = dynamic_offset_; offset < max_offset; offset += sizeof(DynType)) {
if (!memory_->ReadFully(offset, &dyn, sizeof(dyn))) {
last_error_.code = ERROR_MEMORY_INVALID;