Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85d0c3ad authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Add ability to read jit gdb data."

parents 178ede37 150db124
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
  auto process_memory = stack_map->process_memory();
  unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(),
                                 regs, stack_map->process_memory());
  unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch());
  unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore());

  if (num_ignore_frames >= unwinder.NumFrames()) {
+7 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@
#include <stdlib.h>
#include <sys/types.h>

#include <string>
#include <vector>

#include <backtrace/BacktraceMap.h>
#include <unwindstack/Elf.h>
#include <unwindstack/MapInfo.h>
@@ -39,6 +42,10 @@ bool UnwindStackMap::Build() {
  // Create the process memory object.
  process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_);

  // Create a JitDebug object for getting jit unwind information.
  std::vector<std::string> search_libs_{"libart.so", "libartd.so"};
  jit_debug_.reset(new unwindstack::JitDebug(process_memory_, search_libs_));

  if (!stack_maps_->Parse()) {
    return false;
  }
+4 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <memory>

#include <backtrace/BacktraceMap.h>
#include <unwindstack/JitDebug.h>
#include <unwindstack/Maps.h>

class UnwindStackMap : public BacktraceMap {
@@ -41,11 +42,14 @@ class UnwindStackMap : public BacktraceMap {

  const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; }

  unwindstack::JitDebug* GetJitDebug() { return jit_debug_.get(); }

 protected:
  uint64_t GetLoadBias(size_t index) override;

  std::unique_ptr<unwindstack::Maps> stack_maps_;
  std::shared_ptr<unwindstack::Memory> process_memory_;
  std::unique_ptr<unwindstack::JitDebug> jit_debug_;
};

#endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
+3 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ cc_library {
        "Elf.cpp",
        "ElfInterface.cpp",
        "ElfInterfaceArm.cpp",
        "JitDebug.cpp",
        "Log.cpp",
        "MapInfo.cpp",
        "Maps.cpp",
@@ -128,6 +129,7 @@ cc_test {
        "tests/ElfInterfaceTest.cpp",
        "tests/ElfTest.cpp",
        "tests/ElfTestUtils.cpp",
        "tests/JitDebugTest.cpp",
        "tests/LogFake.cpp",
        "tests/MapInfoGetElfTest.cpp",
        "tests/MapInfoGetLoadBiasTest.cpp",
@@ -168,6 +170,7 @@ cc_test {
    data: [
        "tests/files/elf32.xz",
        "tests/files/elf64.xz",
        "tests/files/offline/jit_debug_x86_32/*",
        "tests/files/offline/gnu_debugdata_arm32/*",
        "tests/files/offline/straddle_arm32/*",
        "tests/files/offline/straddle_arm64/*",
+48 −0
Original line number Diff line number Diff line
@@ -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;
Loading