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

Commit 9adfd310 authored by Christopher Ferris's avatar Christopher Ferris Committed by android-build-merger
Browse files

Merge "Do not check arch for format check." am: 70a454e2

am: 28f60ef1

Change-Id: Icbeda570fbe2b80e91fbb8100b57f79ca0faa963
parents 9ade8fcd 28f60ef1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ std::string Unwinder::FormatFrame(size_t frame_num) {
  if (frame_num >= frames_.size()) {
    return "";
  }
  return FormatFrame(frames_[frame_num], regs_->Arch() == ARCH_ARM || regs_->Arch() == ARCH_X86);
  return FormatFrame(frames_[frame_num], regs_->Format32Bit());
}

std::string Unwinder::FormatFrame(const FrameData& frame, bool bits32) {
+4 −0
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ class Regs {

  virtual ArchEnum Arch() = 0;

  virtual bool Format32Bit() = 0;

  virtual void* RawData() = 0;
  virtual uint64_t pc() = 0;
  virtual uint64_t sp() = 0;
@@ -92,6 +94,8 @@ class RegsImpl : public Regs {
  void set_pc(AddressType pc) { pc_ = pc; }
  void set_sp(AddressType sp) { sp_ = sp; }

  bool Format32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); }

  inline AddressType& operator[](size_t reg) { return regs_[reg]; }

  void* RawData() override { return regs_.data(); }
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ class RegsFake : public Regs {

  void IterateRegisters(std::function<void(const char*, uint64_t)>) override {}

  bool Format32Bit() { return false; }

  uint64_t GetAdjustedPc(uint64_t rel_pc, Elf*) override { return rel_pc - 2; }

  bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
+70 −26
Original line number Diff line number Diff line
@@ -28,6 +28,10 @@
#include <unwindstack/Maps.h>
#include <unwindstack/Memory.h>
#include <unwindstack/Regs.h>
#include <unwindstack/RegsArm.h>
#include <unwindstack/RegsArm64.h>
#include <unwindstack/RegsX86.h>
#include <unwindstack/RegsX86_64.h>
#include <unwindstack/Unwinder.h>

#include "ElfFake.h"
@@ -53,7 +57,7 @@ class UnwinderTest : public ::testing::Test {
  static void SetUpTestCase() {
    maps_.FakeClear();
    MapInfo* info = new MapInfo(0x1000, 0x8000, 0, PROT_READ | PROT_WRITE, "/system/fake/libc.so");
    ElfFake* elf = new ElfFake(nullptr);
    ElfFake* elf = new ElfFake(new MemoryFake);
    info->elf = elf;
    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
    maps_.FakeAddMapInfo(info);
@@ -66,31 +70,33 @@ class UnwinderTest : public ::testing::Test {
    maps_.FakeAddMapInfo(info);

    info = new MapInfo(0x20000, 0x22000, 0, PROT_READ | PROT_WRITE, "/system/fake/libunwind.so");
    elf = new ElfFake(nullptr);
    elf = new ElfFake(new MemoryFake);
    info->elf = elf;
    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
    maps_.FakeAddMapInfo(info);

    info = new MapInfo(0x23000, 0x24000, 0, PROT_READ | PROT_WRITE, "/fake/libanother.so");
    elf = new ElfFake(nullptr);
    elf = new ElfFake(new MemoryFake);
    info->elf = elf;
    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
    maps_.FakeAddMapInfo(info);

    info = new MapInfo(0x33000, 0x34000, 0, PROT_READ | PROT_WRITE, "/fake/compressed.so");
    elf = new ElfFake(nullptr);
    elf = new ElfFake(new MemoryFake);
    info->elf = elf;
    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
    maps_.FakeAddMapInfo(info);

    info = new MapInfo(0x43000, 0x44000, 0x1d000, PROT_READ | PROT_WRITE, "/fake/fake.apk");
    elf = new ElfFake(nullptr);
    elf = new ElfFake(new MemoryFake);
    info->elf = elf;
    elf->FakeSetInterface(new ElfInterfaceFake(nullptr));
    maps_.FakeAddMapInfo(info);

    info = new MapInfo(0x53000, 0x54000, 0, PROT_READ | PROT_WRITE, "/fake/fake.oat");
    maps_.FakeAddMapInfo(info);

    process_memory_.reset(new MemoryFake);
  }

  void SetUp() override {
@@ -690,29 +696,67 @@ TEST_F(UnwinderTest, format_frame_static) {
  EXPECT_EQ("  #01 pc 00001000  <unknown>", Unwinder::FormatFrame(frame, true));
}

static std::string ArchToString(ArchEnum arch) {
  if (arch == ARCH_ARM) {
    return "Arm";
  } else if (arch == ARCH_ARM64) {
    return "Arm64";
  } else if (arch == ARCH_X86) {
    return "X86";
  } else if (arch == ARCH_X86_64) {
    return "X86_64";
  } else {
    return "Unknown";
  }
}

// Verify format frame code.
TEST_F(UnwinderTest, format_frame) {
  std::vector<Regs*> reg_list;
  RegsArm* arm = new RegsArm;
  arm->set_pc(0x2300);
  arm->set_sp(0x10000);
  reg_list.push_back(arm);

  RegsArm64* arm64 = new RegsArm64;
  arm64->set_pc(0x2300);
  arm64->set_sp(0x10000);
  reg_list.push_back(arm64);

  RegsX86* x86 = new RegsX86;
  x86->set_pc(0x2300);
  x86->set_sp(0x10000);
  reg_list.push_back(x86);

  RegsX86_64* x86_64 = new RegsX86_64;
  x86_64->set_pc(0x2300);
  x86_64->set_sp(0x10000);
  reg_list.push_back(x86_64);

  for (auto regs : reg_list) {
    ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 10));

  regs_.FakeSetPc(0x2300);
  regs_.FakeSetSp(0x10000);

  Unwinder unwinder(64, &maps_, &regs_, process_memory_);
    Unwinder unwinder(64, &maps_, regs, process_memory_);
    unwinder.Unwind();

    ASSERT_EQ(1U, unwinder.NumFrames());

  regs_.FakeSetArch(ARCH_ARM);
  EXPECT_EQ("  #00 pc 00001300  /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
  regs_.FakeSetArch(ARCH_X86);
  EXPECT_EQ("  #00 pc 00001300  /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));

  regs_.FakeSetArch(ARCH_ARM64);
  EXPECT_EQ("  #00 pc 0000000000001300  /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));
  regs_.FakeSetArch(ARCH_X86_64);
  EXPECT_EQ("  #00 pc 0000000000001300  /system/fake/libc.so (Frame0+10)", unwinder.FormatFrame(0));

  EXPECT_EQ("", unwinder.FormatFrame(1));
    std::string expected;
    switch (regs->Arch()) {
      case ARCH_ARM:
      case ARCH_X86:
        expected = "  #00 pc 00001300  /system/fake/libc.so (Frame0+10)";
        break;
      case ARCH_ARM64:
      case ARCH_X86_64:
        expected = "  #00 pc 0000000000001300  /system/fake/libc.so (Frame0+10)";
        break;
      default:
        expected = "";
    }
    EXPECT_EQ(expected, unwinder.FormatFrame(0))
        << "Mismatch of frame format for regs arch " << ArchToString(regs->Arch());
    delete regs;
  }
}

}  // namespace unwindstack