Merge "Fix GetGlobalVariableOffset with tagged pointer in aarch64"

This commit is contained in:
Treehugger Robot 2020-05-06 05:53:45 +00:00 committed by Gerrit Code Review
commit c3d30bfdff
3 changed files with 50 additions and 0 deletions

View File

@ -124,6 +124,12 @@ bool Elf::GetGlobalVariableOffset(const std::string& name, uint64_t* memory_offs
return false;
}
if (arch() == ARCH_ARM64) {
// Tagged pointer after Android R would lead top byte to have random values
// https://source.android.com/devices/tech/debug/tagged-pointers
vaddr &= (1ULL << 56) - 1;
}
// Check the .data section.
uint64_t vaddr_start = interface_->data_vaddr_start();
if (vaddr >= vaddr_start && vaddr < interface_->data_vaddr_end()) {

View File

@ -55,6 +55,8 @@ class ElfFake : public Elf {
void FakeSetLoadBias(uint64_t load_bias) { load_bias_ = load_bias; }
void FakeSetArch(ArchEnum arch) { arch_ = arch; }
void FakeSetInterface(ElfInterface* interface) { interface_.reset(interface); }
void FakeSetGnuDebugdataInterface(ElfInterface* interface) {
gnu_debugdata_interface_.reset(interface);

View File

@ -438,6 +438,48 @@ TEST_F(ElfTest, get_global_vaddr_in_dynamic_section) {
EXPECT_EQ(0xc080U, offset);
}
TEST_F(ElfTest, get_global_vaddr_with_tagged_pointer) {
ElfFake elf(memory_);
elf.FakeSetValid(true);
elf.FakeSetArch(ARCH_ARM64);
ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
elf.FakeSetInterface(interface);
interface->MockSetDataVaddrStart(0x500);
interface->MockSetDataVaddrEnd(0x600);
interface->MockSetDataOffset(0xa000);
std::string global("something");
EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
.WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x8800000000000580),
::testing::Return(true)));
uint64_t offset;
ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
EXPECT_EQ(0xa080U, offset);
}
TEST_F(ElfTest, get_global_vaddr_without_tagged_pointer) {
ElfFake elf(memory_);
elf.FakeSetValid(true);
elf.FakeSetArch(ARCH_X86_64);
ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
elf.FakeSetInterface(interface);
interface->MockSetDataVaddrStart(0x8800000000000500);
interface->MockSetDataVaddrEnd(0x8800000000000600);
interface->MockSetDataOffset(0x880000000000a000);
std::string global("something");
EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
.WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x8800000000000580),
::testing::Return(true)));
uint64_t offset;
ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
EXPECT_EQ(0x880000000000a080U, offset);
}
TEST_F(ElfTest, is_valid_pc_elf_invalid) {
ElfFake elf(memory_);
elf.FakeSetValid(false);