Merge "Use elf offset in signal step check."
This commit is contained in:
commit
25cd25168a
|
@ -251,6 +251,7 @@ cc_defaults {
|
|||
"tests/files/offline/shared_lib_in_apk_arm64/*",
|
||||
"tests/files/offline/shared_lib_in_apk_memory_only_arm64/*",
|
||||
"tests/files/offline/shared_lib_in_apk_single_map_arm64/*",
|
||||
"tests/files/offline/signal_load_bias_arm/*",
|
||||
"tests/files/offline/straddle_arm/*",
|
||||
"tests/files/offline/straddle_arm64/*",
|
||||
],
|
||||
|
|
|
@ -173,7 +173,12 @@ bool Elf::StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memor
|
|||
if (!valid_) {
|
||||
return false;
|
||||
}
|
||||
return regs->StepIfSignalHandler(rel_pc, this, process_memory);
|
||||
|
||||
// Convert the rel_pc to an elf_offset.
|
||||
if (rel_pc < static_cast<uint64_t>(load_bias_)) {
|
||||
return false;
|
||||
}
|
||||
return regs->StepIfSignalHandler(rel_pc - load_bias_, this, process_memory);
|
||||
}
|
||||
|
||||
// The relative pc is always relative to the start of the map from which it comes.
|
||||
|
|
|
@ -127,12 +127,12 @@ Regs* RegsArm::CreateFromUcontext(void* ucontext) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
|
||||
bool RegsArm::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
||||
uint32_t data;
|
||||
Memory* elf_memory = elf->memory();
|
||||
// Read from elf memory since it is usually more expensive to read from
|
||||
// process memory.
|
||||
if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data))) {
|
||||
if (!elf_memory->ReadFully(elf_offset, &data, sizeof(data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,12 +126,12 @@ Regs* RegsArm64::CreateFromUcontext(void* ucontext) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
|
||||
bool RegsArm64::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
||||
uint64_t data;
|
||||
Memory* elf_memory = elf->memory();
|
||||
// Read from elf memory since it is usually more expensive to read from
|
||||
// process memory.
|
||||
if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data))) {
|
||||
if (!elf_memory->ReadFully(elf_offset, &data, sizeof(data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,13 +129,13 @@ Regs* RegsMips::CreateFromUcontext(void* ucontext) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
|
||||
bool RegsMips::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
||||
uint64_t data;
|
||||
uint64_t offset = 0;
|
||||
Memory* elf_memory = elf->memory();
|
||||
// Read from elf memory since it is usually more expensive to read from
|
||||
// process memory.
|
||||
if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data))) {
|
||||
if (!elf_memory->ReadFully(elf_offset, &data, sizeof(data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,12 +127,12 @@ Regs* RegsMips64::CreateFromUcontext(void* ucontext) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
bool RegsMips64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
|
||||
bool RegsMips64::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
||||
uint64_t data;
|
||||
Memory* elf_memory = elf->memory();
|
||||
// Read from elf memory since it is usually more expensive to read from
|
||||
// process memory.
|
||||
if (!elf_memory->Read(rel_pc, &data, sizeof(data))) {
|
||||
if (!elf_memory->Read(elf_offset, &data, sizeof(data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,12 +119,12 @@ Regs* RegsX86::CreateFromUcontext(void* ucontext) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
|
||||
bool RegsX86::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
||||
uint64_t data;
|
||||
Memory* elf_memory = elf->memory();
|
||||
// Read from elf memory since it is usually more expensive to read from
|
||||
// process memory.
|
||||
if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data))) {
|
||||
if (!elf_memory->ReadFully(elf_offset, &data, sizeof(data))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -139,17 +139,17 @@ Regs* RegsX86_64::CreateFromUcontext(void* ucontext) {
|
|||
return regs;
|
||||
}
|
||||
|
||||
bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) {
|
||||
bool RegsX86_64::StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) {
|
||||
uint64_t data;
|
||||
Memory* elf_memory = elf->memory();
|
||||
// Read from elf memory since it is usually more expensive to read from
|
||||
// process memory.
|
||||
if (!elf_memory->ReadFully(rel_pc, &data, sizeof(data)) || data != 0x0f0000000fc0c748) {
|
||||
if (!elf_memory->ReadFully(elf_offset, &data, sizeof(data)) || data != 0x0f0000000fc0c748) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t data2;
|
||||
if (!elf_memory->ReadFully(rel_pc + 8, &data2, sizeof(data2)) || data2 != 0x0f05) {
|
||||
if (!elf_memory->ReadFully(elf_offset + 8, &data2, sizeof(data2)) || data2 != 0x0f05) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class Regs {
|
|||
|
||||
virtual uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf) = 0;
|
||||
|
||||
virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0;
|
||||
virtual bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) = 0;
|
||||
|
||||
virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class RegsArm : public RegsImpl<uint32_t> {
|
|||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
||||
void IterateRegisters(std::function<void(const char*, uint64_t)>) override final;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class RegsArm64 : public RegsImpl<uint64_t> {
|
|||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
||||
void IterateRegisters(std::function<void(const char*, uint64_t)>) override final;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class RegsMips : public RegsImpl<uint32_t> {
|
|||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
||||
void IterateRegisters(std::function<void(const char*, uint64_t)>) override final;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class RegsMips64 : public RegsImpl<uint64_t> {
|
|||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
||||
void IterateRegisters(std::function<void(const char*, uint64_t)>) override final;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class RegsX86 : public RegsImpl<uint32_t> {
|
|||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
||||
void SetFromUcontext(x86_ucontext_t* ucontext);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ class RegsX86_64 : public RegsImpl<uint64_t> {
|
|||
|
||||
bool SetPcFromReturnAddress(Memory* process_memory) override;
|
||||
|
||||
bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) override;
|
||||
bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) override;
|
||||
|
||||
void SetFromUcontext(x86_64_ucontext_t* ucontext);
|
||||
|
||||
|
|
|
@ -104,6 +104,8 @@ class ElfTest : public ::testing::Test {
|
|||
memory_->SetMemory(0x100, &phdr, sizeof(phdr));
|
||||
}
|
||||
|
||||
void VerifyStepIfSignalHandler(uint64_t load_bias);
|
||||
|
||||
MemoryFake* memory_;
|
||||
};
|
||||
|
||||
|
@ -281,7 +283,7 @@ TEST_F(ElfTest, rel_pc) {
|
|||
ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info));
|
||||
}
|
||||
|
||||
TEST_F(ElfTest, step_in_signal_map) {
|
||||
void ElfTest::VerifyStepIfSignalHandler(uint64_t load_bias) {
|
||||
ElfFake elf(memory_);
|
||||
|
||||
RegsArm regs;
|
||||
|
@ -290,6 +292,7 @@ TEST_F(ElfTest, step_in_signal_map) {
|
|||
|
||||
ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
|
||||
elf.FakeSetInterface(interface);
|
||||
elf.FakeSetLoadBias(load_bias);
|
||||
|
||||
memory_->SetData32(0x3000, 0xdf0027ad);
|
||||
MemoryFake process_memory;
|
||||
|
@ -299,12 +302,20 @@ TEST_F(ElfTest, step_in_signal_map) {
|
|||
}
|
||||
|
||||
elf.FakeSetValid(true);
|
||||
ASSERT_TRUE(elf.StepIfSignalHandler(0x3000, ®s, &process_memory));
|
||||
ASSERT_TRUE(elf.StepIfSignalHandler(0x3000 + load_bias, ®s, &process_memory));
|
||||
EXPECT_EQ(ERROR_NONE, elf.GetLastErrorCode());
|
||||
EXPECT_EQ(15U, regs.pc());
|
||||
EXPECT_EQ(13U, regs.sp());
|
||||
}
|
||||
|
||||
TEST_F(ElfTest, step_in_signal_map) {
|
||||
VerifyStepIfSignalHandler(0);
|
||||
}
|
||||
|
||||
TEST_F(ElfTest, step_in_signal_map_non_zero_load_bias) {
|
||||
VerifyStepIfSignalHandler(0x1000);
|
||||
}
|
||||
|
||||
class ElfInterfaceMock : public ElfInterface {
|
||||
public:
|
||||
ElfInterfaceMock(Memory* memory) : ElfInterface(memory) {}
|
||||
|
|
|
@ -1629,4 +1629,72 @@ TEST_F(UnwindOfflineTest, eh_frame_bias_x86) {
|
|||
EXPECT_EQ(0xfffe1d74ULL, unwinder.frames()[10].sp);
|
||||
}
|
||||
|
||||
TEST_F(UnwindOfflineTest, signal_load_bias_arm) {
|
||||
ASSERT_NO_FATAL_FAILURE(Init("signal_load_bias_arm/", ARCH_ARM));
|
||||
|
||||
Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
|
||||
unwinder.Unwind();
|
||||
|
||||
std::string frame_info(DumpFrames(unwinder));
|
||||
ASSERT_EQ(17U, unwinder.NumFrames()) << "Unwind:\n" << frame_info;
|
||||
EXPECT_EQ(
|
||||
" #00 pc 0029ef9e libunwindstack_unit_test (SignalInnerFunction+10)\n"
|
||||
" #01 pc 0029efa7 libunwindstack_unit_test (SignalMiddleFunction+2)\n"
|
||||
" #02 pc 0029efaf libunwindstack_unit_test (SignalOuterFunction+2)\n"
|
||||
" #03 pc 002a280b libunwindstack_unit_test (unwindstack::SignalCallerHandler(int, "
|
||||
"siginfo*, void*)+10)\n"
|
||||
" #04 pc 00058bd4 libc.so (__restore)\n"
|
||||
" #05 pc 0029f01e libunwindstack_unit_test (InnerFunction+106)\n"
|
||||
" #06 pc 0029f633 libunwindstack_unit_test (MiddleFunction+16)\n"
|
||||
" #07 pc 0029f64b libunwindstack_unit_test (OuterFunction+16)\n"
|
||||
" #08 pc 002a1711 libunwindstack_unit_test (unwindstack::RemoteThroughSignal(int, unsigned "
|
||||
"int)+260)\n"
|
||||
" #09 pc 002a1603 libunwindstack_unit_test "
|
||||
"(unwindstack::UnwindTest_remote_through_signal_Test::TestBody()+10)\n"
|
||||
" #10 pc 002c8fe3 libunwindstack_unit_test (testing::Test::Run()+130)\n"
|
||||
" #11 pc 002c9b25 libunwindstack_unit_test (testing::TestInfo::Run()+184)\n"
|
||||
" #12 pc 002c9e27 libunwindstack_unit_test (testing::TestSuite::Run()+202)\n"
|
||||
" #13 pc 002d193d libunwindstack_unit_test "
|
||||
"(testing::internal::UnitTestImpl::RunAllTests()+660)\n"
|
||||
" #14 pc 002d160b libunwindstack_unit_test (testing::UnitTest::Run()+134)\n"
|
||||
" #15 pc 002de035 libunwindstack_unit_test (IsolateMain+680)\n"
|
||||
" #16 pc 00058155 libc.so (__libc_init+68)\n",
|
||||
frame_info);
|
||||
|
||||
EXPECT_EQ(0xb6955f9eULL, unwinder.frames()[0].pc);
|
||||
EXPECT_EQ(0xf2790ce8ULL, unwinder.frames()[0].sp);
|
||||
EXPECT_EQ(0xb6955fa7ULL, unwinder.frames()[1].pc);
|
||||
EXPECT_EQ(0xf2790ce8ULL, unwinder.frames()[1].sp);
|
||||
EXPECT_EQ(0xb6955fafULL, unwinder.frames()[2].pc);
|
||||
EXPECT_EQ(0xf2790cf0ULL, unwinder.frames()[2].sp);
|
||||
EXPECT_EQ(0xb695980bULL, unwinder.frames()[3].pc);
|
||||
EXPECT_EQ(0xf2790cf8ULL, unwinder.frames()[3].sp);
|
||||
EXPECT_EQ(0xf23febd4ULL, unwinder.frames()[4].pc);
|
||||
EXPECT_EQ(0xf2790d10ULL, unwinder.frames()[4].sp);
|
||||
EXPECT_EQ(0xb695601eULL, unwinder.frames()[5].pc);
|
||||
EXPECT_EQ(0xffe67798ULL, unwinder.frames()[5].sp);
|
||||
EXPECT_EQ(0xb6956633ULL, unwinder.frames()[6].pc);
|
||||
EXPECT_EQ(0xffe67890ULL, unwinder.frames()[6].sp);
|
||||
EXPECT_EQ(0xb695664bULL, unwinder.frames()[7].pc);
|
||||
EXPECT_EQ(0xffe678a0ULL, unwinder.frames()[7].sp);
|
||||
EXPECT_EQ(0xb6958711ULL, unwinder.frames()[8].pc);
|
||||
EXPECT_EQ(0xffe678b0ULL, unwinder.frames()[8].sp);
|
||||
EXPECT_EQ(0xb6958603ULL, unwinder.frames()[9].pc);
|
||||
EXPECT_EQ(0xffe67ac8ULL, unwinder.frames()[9].sp);
|
||||
EXPECT_EQ(0xb697ffe3ULL, unwinder.frames()[10].pc);
|
||||
EXPECT_EQ(0xffe67ad8ULL, unwinder.frames()[10].sp);
|
||||
EXPECT_EQ(0xb6980b25ULL, unwinder.frames()[11].pc);
|
||||
EXPECT_EQ(0xffe67ae8ULL, unwinder.frames()[11].sp);
|
||||
EXPECT_EQ(0xb6980e27ULL, unwinder.frames()[12].pc);
|
||||
EXPECT_EQ(0xffe67b18ULL, unwinder.frames()[12].sp);
|
||||
EXPECT_EQ(0xb698893dULL, unwinder.frames()[13].pc);
|
||||
EXPECT_EQ(0xffe67b48ULL, unwinder.frames()[13].sp);
|
||||
EXPECT_EQ(0xb698860bULL, unwinder.frames()[14].pc);
|
||||
EXPECT_EQ(0xffe67bb0ULL, unwinder.frames()[14].sp);
|
||||
EXPECT_EQ(0xb6995035ULL, unwinder.frames()[15].pc);
|
||||
EXPECT_EQ(0xffe67bd0ULL, unwinder.frames()[15].sp);
|
||||
EXPECT_EQ(0xf23fe155ULL, unwinder.frames()[16].pc);
|
||||
EXPECT_EQ(0xffe67d10ULL, unwinder.frames()[16].sp);
|
||||
}
|
||||
|
||||
} // namespace unwindstack
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,4 @@
|
|||
b66b7000-b670c000 r--p 0 00:00 0 libunwindstack_unit_test
|
||||
b670c000-b69a8000 r-xp 54000 00:00 0 libunwindstack_unit_test
|
||||
f23a6000-f23d0000 r--p 0 00:00 0 libc.so
|
||||
f23d0000-f2451000 r-xp 29000 00:00 0 libc.so
|
|
@ -0,0 +1,16 @@
|
|||
r0: b69b7c84
|
||||
r1: 1
|
||||
r2: 1
|
||||
r3: 1
|
||||
r4: f1e52bd0
|
||||
r5: f1e11000
|
||||
r6: f1e52bd0
|
||||
r7: f1e52a38
|
||||
r8: f1e11000
|
||||
r9: 5de82a8f
|
||||
r10: f1e06030
|
||||
r11: f1e6d080
|
||||
ip: ffe67a88
|
||||
sp: f2790ce8
|
||||
lr: b6955fab
|
||||
pc: b6955f9e
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue