summaryrefslogtreecommitdiff
path: root/libunwindstack/Elf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/Elf.cpp')
-rw-r--r--libunwindstack/Elf.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index 5ec4a3d..220e549 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -103,6 +103,37 @@ bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offse
addr, load_bias_, name, func_offset)));
}
+bool Elf::GetGlobalVariable(const std::string& name, uint64_t* memory_address) {
+ if (!valid_) {
+ return false;
+ }
+
+ if (!interface_->GetGlobalVariable(name, memory_address) &&
+ (gnu_debugdata_interface_ == nullptr ||
+ !gnu_debugdata_interface_->GetGlobalVariable(name, memory_address))) {
+ return false;
+ }
+
+ // Adjust by the load bias.
+ if (*memory_address < load_bias_) {
+ return false;
+ }
+
+ *memory_address -= load_bias_;
+
+ // If this winds up in the dynamic section, then we might need to adjust
+ // the address.
+ uint64_t dynamic_end = interface_->dynamic_vaddr() + interface_->dynamic_size();
+ if (*memory_address >= interface_->dynamic_vaddr() && *memory_address < dynamic_end) {
+ if (interface_->dynamic_vaddr() > interface_->dynamic_offset()) {
+ *memory_address -= interface_->dynamic_vaddr() - interface_->dynamic_offset();
+ } else {
+ *memory_address += interface_->dynamic_offset() - interface_->dynamic_vaddr();
+ }
+ }
+ return true;
+}
+
// The relative pc is always relative to the start of the map from which it comes.
bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs,
Memory* process_memory, bool* finished) {
@@ -160,6 +191,23 @@ void Elf::GetInfo(Memory* memory, bool* valid, uint64_t* size) {
}
}
+bool Elf::IsValidPc(uint64_t pc) {
+ if (!valid_ || pc < load_bias_) {
+ return false;
+ }
+ pc -= load_bias_;
+
+ if (interface_->IsValidPc(pc)) {
+ return true;
+ }
+
+ if (gnu_debugdata_interface_ != nullptr && gnu_debugdata_interface_->IsValidPc(pc)) {
+ return true;
+ }
+
+ return false;
+}
+
ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) {
if (!IsValidElf(memory)) {
return nullptr;