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

Commit 239b23f6 authored by Christopher Ferris's avatar Christopher Ferris Committed by android-build-merger
Browse files

Merge "Add ability to read jit gdb data." am: 85d0c3ad

am: 307d8865

Change-Id: I9dccca5a720843aeb418afce9aa383b69c8d994e
parents 8d8d8baa 307d8865
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