Merge "libunwindstack: make machine type a property of Regs." am: 75a40988c0
am: 310f3e114a
Change-Id: I319cbb0ca2bbb569f7c8e989764243825a0cdeea
This commit is contained in:
commit
dca8180110
7 changed files with 44 additions and 20 deletions
|
|
@ -160,7 +160,8 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t*
|
||||||
// one extra function call appearing in the unwind.
|
// one extra function call appearing in the unwind.
|
||||||
unwindstack::RegsGetLocal(regs.get());
|
unwindstack::RegsGetLocal(regs.get());
|
||||||
} else {
|
} else {
|
||||||
regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::GetMachineType(), ucontext));
|
regs.reset(
|
||||||
|
unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentMachineType(), ucontext));
|
||||||
}
|
}
|
||||||
|
|
||||||
error_ = BACKTRACE_UNWIND_NO_ERROR;
|
error_ = BACKTRACE_UNWIND_NO_ERROR;
|
||||||
|
|
@ -177,10 +178,10 @@ std::string UnwindStackPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offse
|
||||||
bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) {
|
bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) {
|
||||||
std::unique_ptr<unwindstack::Regs> regs;
|
std::unique_ptr<unwindstack::Regs> regs;
|
||||||
if (context == nullptr) {
|
if (context == nullptr) {
|
||||||
uint32_t machine_type;
|
regs.reset(unwindstack::Regs::RemoteGet(Tid()));
|
||||||
regs.reset(unwindstack::Regs::RemoteGet(Tid(), &machine_type));
|
|
||||||
} else {
|
} else {
|
||||||
regs.reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::GetMachineType(), context));
|
regs.reset(
|
||||||
|
unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentMachineType(), context));
|
||||||
}
|
}
|
||||||
|
|
||||||
error_ = BACKTRACE_UNWIND_NO_ERROR;
|
error_ = BACKTRACE_UNWIND_NO_ERROR;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@ bool RegsImpl<AddressType>::GetReturnAddressFromDefault(Memory* memory, uint64_t
|
||||||
RegsArm::RegsArm()
|
RegsArm::RegsArm()
|
||||||
: RegsImpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP, Location(LOCATION_REGISTER, ARM_REG_LR)) {}
|
: RegsImpl<uint32_t>(ARM_REG_LAST, ARM_REG_SP, Location(LOCATION_REGISTER, ARM_REG_LR)) {}
|
||||||
|
|
||||||
|
uint32_t RegsArm::MachineType() {
|
||||||
|
return EM_ARM;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t RegsArm::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
uint64_t RegsArm::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
||||||
if (!elf->valid()) {
|
if (!elf->valid()) {
|
||||||
return rel_pc;
|
return rel_pc;
|
||||||
|
|
@ -90,6 +94,10 @@ void RegsArm::SetFromRaw() {
|
||||||
RegsArm64::RegsArm64()
|
RegsArm64::RegsArm64()
|
||||||
: RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
|
: RegsImpl<uint64_t>(ARM64_REG_LAST, ARM64_REG_SP, Location(LOCATION_REGISTER, ARM64_REG_LR)) {}
|
||||||
|
|
||||||
|
uint32_t RegsArm64::MachineType() {
|
||||||
|
return EM_AARCH64;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t RegsArm64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
uint64_t RegsArm64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
||||||
if (!elf->valid()) {
|
if (!elf->valid()) {
|
||||||
return rel_pc;
|
return rel_pc;
|
||||||
|
|
@ -109,6 +117,10 @@ void RegsArm64::SetFromRaw() {
|
||||||
RegsX86::RegsX86()
|
RegsX86::RegsX86()
|
||||||
: RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {}
|
: RegsImpl<uint32_t>(X86_REG_LAST, X86_REG_SP, Location(LOCATION_SP_OFFSET, -4)) {}
|
||||||
|
|
||||||
|
uint32_t RegsX86::MachineType() {
|
||||||
|
return EM_386;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t RegsX86::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
uint64_t RegsX86::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
||||||
if (!elf->valid()) {
|
if (!elf->valid()) {
|
||||||
return rel_pc;
|
return rel_pc;
|
||||||
|
|
@ -128,6 +140,10 @@ void RegsX86::SetFromRaw() {
|
||||||
RegsX86_64::RegsX86_64()
|
RegsX86_64::RegsX86_64()
|
||||||
: RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {}
|
: RegsImpl<uint64_t>(X86_64_REG_LAST, X86_64_REG_SP, Location(LOCATION_SP_OFFSET, -8)) {}
|
||||||
|
|
||||||
|
uint32_t RegsX86_64::MachineType() {
|
||||||
|
return EM_X86_64;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t RegsX86_64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
uint64_t RegsX86_64::GetAdjustedPc(uint64_t rel_pc, Elf* elf) {
|
||||||
if (!elf->valid()) {
|
if (!elf->valid()) {
|
||||||
return rel_pc;
|
return rel_pc;
|
||||||
|
|
@ -212,7 +228,7 @@ static Regs* ReadX86_64(void* remote_data) {
|
||||||
|
|
||||||
// This function assumes that reg_data is already aligned to a 64 bit value.
|
// This function assumes that reg_data is already aligned to a 64 bit value.
|
||||||
// If not this could crash with an unaligned access.
|
// If not this could crash with an unaligned access.
|
||||||
Regs* Regs::RemoteGet(pid_t pid, uint32_t* machine_type) {
|
Regs* Regs::RemoteGet(pid_t pid) {
|
||||||
// Make the buffer large enough to contain the largest registers type.
|
// Make the buffer large enough to contain the largest registers type.
|
||||||
std::vector<uint64_t> buffer(MAX_USER_REGS_SIZE / sizeof(uint64_t));
|
std::vector<uint64_t> buffer(MAX_USER_REGS_SIZE / sizeof(uint64_t));
|
||||||
struct iovec io;
|
struct iovec io;
|
||||||
|
|
@ -225,16 +241,12 @@ Regs* Regs::RemoteGet(pid_t pid, uint32_t* machine_type) {
|
||||||
|
|
||||||
switch (io.iov_len) {
|
switch (io.iov_len) {
|
||||||
case sizeof(x86_user_regs):
|
case sizeof(x86_user_regs):
|
||||||
*machine_type = EM_386;
|
|
||||||
return ReadX86(buffer.data());
|
return ReadX86(buffer.data());
|
||||||
case sizeof(x86_64_user_regs):
|
case sizeof(x86_64_user_regs):
|
||||||
*machine_type = EM_X86_64;
|
|
||||||
return ReadX86_64(buffer.data());
|
return ReadX86_64(buffer.data());
|
||||||
case sizeof(arm_user_regs):
|
case sizeof(arm_user_regs):
|
||||||
*machine_type = EM_ARM;
|
|
||||||
return ReadArm(buffer.data());
|
return ReadArm(buffer.data());
|
||||||
case sizeof(arm64_user_regs):
|
case sizeof(arm64_user_regs):
|
||||||
*machine_type = EM_AARCH64;
|
|
||||||
return ReadArm64(buffer.data());
|
return ReadArm64(buffer.data());
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -320,7 +332,7 @@ Regs* Regs::CreateFromUcontext(uint32_t machine_type, void* ucontext) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Regs::GetMachineType() {
|
uint32_t Regs::CurrentMachineType() {
|
||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
return EM_ARM;
|
return EM_ARM;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ class Regs {
|
||||||
: total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {}
|
: total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {}
|
||||||
virtual ~Regs() = default;
|
virtual ~Regs() = default;
|
||||||
|
|
||||||
|
virtual uint32_t MachineType() = 0;
|
||||||
|
|
||||||
virtual void* RawData() = 0;
|
virtual void* RawData() = 0;
|
||||||
virtual uint64_t pc() = 0;
|
virtual uint64_t pc() = 0;
|
||||||
virtual uint64_t sp() = 0;
|
virtual uint64_t sp() = 0;
|
||||||
|
|
@ -64,8 +66,8 @@ class Regs {
|
||||||
uint16_t sp_reg() { return sp_reg_; }
|
uint16_t sp_reg() { return sp_reg_; }
|
||||||
uint16_t total_regs() { return total_regs_; }
|
uint16_t total_regs() { return total_regs_; }
|
||||||
|
|
||||||
static uint32_t GetMachineType();
|
static uint32_t CurrentMachineType();
|
||||||
static Regs* RemoteGet(pid_t pid, uint32_t* machine_type);
|
static Regs* RemoteGet(pid_t pid);
|
||||||
static Regs* CreateFromUcontext(uint32_t machine_type, void* ucontext);
|
static Regs* CreateFromUcontext(uint32_t machine_type, void* ucontext);
|
||||||
static Regs* CreateFromLocal();
|
static Regs* CreateFromLocal();
|
||||||
|
|
||||||
|
|
@ -105,6 +107,8 @@ class RegsArm : public RegsImpl<uint32_t> {
|
||||||
RegsArm();
|
RegsArm();
|
||||||
virtual ~RegsArm() = default;
|
virtual ~RegsArm() = default;
|
||||||
|
|
||||||
|
virtual uint32_t MachineType() override final;
|
||||||
|
|
||||||
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
||||||
|
|
||||||
void SetFromRaw() override;
|
void SetFromRaw() override;
|
||||||
|
|
@ -117,6 +121,8 @@ class RegsArm64 : public RegsImpl<uint64_t> {
|
||||||
RegsArm64();
|
RegsArm64();
|
||||||
virtual ~RegsArm64() = default;
|
virtual ~RegsArm64() = default;
|
||||||
|
|
||||||
|
virtual uint32_t MachineType() override final;
|
||||||
|
|
||||||
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
||||||
|
|
||||||
void SetFromRaw() override;
|
void SetFromRaw() override;
|
||||||
|
|
@ -129,6 +135,8 @@ class RegsX86 : public RegsImpl<uint32_t> {
|
||||||
RegsX86();
|
RegsX86();
|
||||||
virtual ~RegsX86() = default;
|
virtual ~RegsX86() = default;
|
||||||
|
|
||||||
|
virtual uint32_t MachineType() override final;
|
||||||
|
|
||||||
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
||||||
|
|
||||||
void SetFromRaw() override;
|
void SetFromRaw() override;
|
||||||
|
|
@ -143,6 +151,8 @@ class RegsX86_64 : public RegsImpl<uint64_t> {
|
||||||
RegsX86_64();
|
RegsX86_64();
|
||||||
virtual ~RegsX86_64() = default;
|
virtual ~RegsX86_64() = default;
|
||||||
|
|
||||||
|
virtual uint32_t MachineType() override final;
|
||||||
|
|
||||||
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
|
||||||
|
|
||||||
void SetFromRaw() override;
|
void SetFromRaw() override;
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@ class RegsFake : public RegsImpl<TypeParam> {
|
||||||
: RegsImpl<TypeParam>(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {}
|
: RegsImpl<TypeParam>(total_regs, sp_reg, Regs::Location(Regs::LOCATION_UNKNOWN, 0)) {}
|
||||||
virtual ~RegsFake() = default;
|
virtual ~RegsFake() = default;
|
||||||
|
|
||||||
|
uint32_t MachineType() override { return 0; }
|
||||||
|
|
||||||
uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
|
uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
|
||||||
void SetFromRaw() override {}
|
void SetFromRaw() override {}
|
||||||
bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
|
bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,8 @@ class RegsTestImpl : public RegsImpl<TypeParam> {
|
||||||
: RegsImpl<TypeParam>(total_regs, regs_sp, return_loc) {}
|
: RegsImpl<TypeParam>(total_regs, regs_sp, return_loc) {}
|
||||||
virtual ~RegsTestImpl() = default;
|
virtual ~RegsTestImpl() = default;
|
||||||
|
|
||||||
|
uint32_t MachineType() override { return 0; }
|
||||||
|
|
||||||
uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
|
uint64_t GetAdjustedPc(uint64_t, Elf*) override { return 0; }
|
||||||
void SetFromRaw() override {}
|
void SetFromRaw() override {}
|
||||||
bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
|
bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,7 @@ TEST(UnwindTest, remote) {
|
||||||
RemoteMaps maps(pid);
|
RemoteMaps maps(pid);
|
||||||
ASSERT_TRUE(maps.Parse());
|
ASSERT_TRUE(maps.Parse());
|
||||||
MemoryRemote memory(pid);
|
MemoryRemote memory(pid);
|
||||||
uint32_t machine_type;
|
std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
|
||||||
std::unique_ptr<Regs> regs(Regs::RemoteGet(pid, &machine_type));
|
|
||||||
ASSERT_TRUE(regs.get() != nullptr);
|
ASSERT_TRUE(regs.get() != nullptr);
|
||||||
|
|
||||||
VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionOrder);
|
VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionOrder);
|
||||||
|
|
@ -254,7 +253,7 @@ TEST(UnwindTest, from_context) {
|
||||||
|
|
||||||
LocalMaps maps;
|
LocalMaps maps;
|
||||||
ASSERT_TRUE(maps.Parse());
|
ASSERT_TRUE(maps.Parse());
|
||||||
std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(Regs::GetMachineType(), ucontext));
|
std::unique_ptr<Regs> regs(Regs::CreateFromUcontext(Regs::CurrentMachineType(), ucontext));
|
||||||
MemoryLocal memory;
|
MemoryLocal memory;
|
||||||
|
|
||||||
VerifyUnwind(tid.load(), &memory, &maps, regs.get(), kFunctionOrder);
|
VerifyUnwind(tid.load(), &memory, &maps, regs.get(), kFunctionOrder);
|
||||||
|
|
@ -293,8 +292,7 @@ static void RemoteThroughSignal(unsigned int sa_flags) {
|
||||||
RemoteMaps maps(pid);
|
RemoteMaps maps(pid);
|
||||||
ASSERT_TRUE(maps.Parse());
|
ASSERT_TRUE(maps.Parse());
|
||||||
MemoryRemote memory(pid);
|
MemoryRemote memory(pid);
|
||||||
uint32_t machine_type;
|
std::unique_ptr<Regs> regs(Regs::RemoteGet(pid));
|
||||||
std::unique_ptr<Regs> regs(Regs::RemoteGet(pid, &machine_type));
|
|
||||||
ASSERT_TRUE(regs.get() != nullptr);
|
ASSERT_TRUE(regs.get() != nullptr);
|
||||||
|
|
||||||
VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionSignalOrder);
|
VerifyUnwind(pid, &memory, &maps, regs.get(), kFunctionSignalOrder);
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,7 @@ void DoUnwind(pid_t pid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t machine_type;
|
unwindstack::Regs* regs = unwindstack::Regs::RemoteGet(pid);
|
||||||
unwindstack::Regs* regs = unwindstack::Regs::RemoteGet(pid, &machine_type);
|
|
||||||
if (regs == nullptr) {
|
if (regs == nullptr) {
|
||||||
printf("Unable to get remote reg data\n");
|
printf("Unable to get remote reg data\n");
|
||||||
return;
|
return;
|
||||||
|
|
@ -71,7 +70,7 @@ void DoUnwind(pid_t pid) {
|
||||||
|
|
||||||
bool bits32 = true;
|
bool bits32 = true;
|
||||||
printf("ABI: ");
|
printf("ABI: ");
|
||||||
switch (machine_type) {
|
switch (regs->MachineType()) {
|
||||||
case EM_ARM:
|
case EM_ARM:
|
||||||
printf("arm");
|
printf("arm");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue