splhack updated this revision to Diff 532163. splhack added a comment. removed abandoned dependency
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D152757/new/ https://reviews.llvm.org/D152757 Files: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/unittests/ObjectFile/ELF/CMakeLists.txt lldb/unittests/ObjectFile/ELF/Inputs/liboffset-test.so lldb/unittests/ObjectFile/ELF/Inputs/offset-test.bin lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp Index: lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp =================================================================== --- lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -156,6 +156,39 @@ EXPECT_EQ(Spec.GetUUID(), Uuid); } +TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithNormalFile) { + std::string SO = GetInputFilePath("liboffset-test.so"); + ModuleSpecList Specs; + ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs)); + ModuleSpec Spec; + ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; + UUID Uuid; + Uuid.SetFromStringRef("7D6E4738"); + EXPECT_EQ(Spec.GetUUID(), Uuid); + EXPECT_EQ(Spec.GetObjectOffset(), 0UL); + EXPECT_EQ(Spec.GetObjectSize(), 3600UL); + EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 3600UL); +} + +TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithOffsetFile) { + // The contents of offset-test.bin are + // - 0-1023: \0 + // - 1024-4623: liboffset-test.so (offset: 1024, size: 3600, CRC32: 7D6E4738) + // - 4624-4639: \0 + std::string SO = GetInputFilePath("offset-test.bin"); + ModuleSpecList Specs; + ASSERT_EQ( + 1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 1024, 3600, Specs)); + ModuleSpec Spec; + ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; + UUID Uuid; + Uuid.SetFromStringRef("7D6E4738"); + EXPECT_EQ(Spec.GetUUID(), Uuid); + EXPECT_EQ(Spec.GetObjectOffset(), 1024UL); + EXPECT_EQ(Spec.GetObjectSize(), 3600UL); + EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 4640UL); +} + TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) { /* // nosym-entrypoint-arm-thumb.s Index: lldb/unittests/ObjectFile/ELF/CMakeLists.txt =================================================================== --- lldb/unittests/ObjectFile/ELF/CMakeLists.txt +++ lldb/unittests/ObjectFile/ELF/CMakeLists.txt @@ -11,5 +11,7 @@ set(test_inputs early-section-headers.so + liboffset-test.so + offset-test.bin ) add_unittest_inputs(ObjectFileELFTests "${test_inputs}") Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -555,6 +555,14 @@ if (header.Parse(data, &header_offset)) { if (data_sp) { ModuleSpec spec(file); + // In Android API level 23 and above, bionic dynamic linker is able to + // load .so file directly from zip file. In that case, .so file is + // page aligned and uncompressed, and this module spec should retain the + // .so file offset and file size to pass through the information from + // lldb-server to LLDB. For normal file, file_offset should be 0, + // length should be the size of the file. + spec.SetObjectOffset(file_offset); + spec.SetObjectSize(length); const uint32_t sub_type = subTypeFromElfHeader(header); spec.GetArchitecture().SetArchitecture( @@ -586,8 +594,12 @@ __FUNCTION__, file.GetPath().c_str()); } + // When ELF file does not contain GNU build ID, the later code will + // calculate CRC32 with this data_sp file_offset and length. It is + // important for Android zip .so file, which is a slice of a file, + // to not access the outside of the file slice range. if (data_sp->GetByteSize() < length) - data_sp = MapFileData(file, -1, file_offset); + data_sp = MapFileData(file, length, file_offset); if (data_sp) data.SetData(data_sp); // In case there is header extension in the section #0, the header we
Index: lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp =================================================================== --- lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp +++ lldb/unittests/ObjectFile/ELF/TestObjectFileELF.cpp @@ -156,6 +156,39 @@ EXPECT_EQ(Spec.GetUUID(), Uuid); } +TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithNormalFile) { + std::string SO = GetInputFilePath("liboffset-test.so"); + ModuleSpecList Specs; + ASSERT_EQ(1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 0, 0, Specs)); + ModuleSpec Spec; + ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; + UUID Uuid; + Uuid.SetFromStringRef("7D6E4738"); + EXPECT_EQ(Spec.GetUUID(), Uuid); + EXPECT_EQ(Spec.GetObjectOffset(), 0UL); + EXPECT_EQ(Spec.GetObjectSize(), 3600UL); + EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 3600UL); +} + +TEST_F(ObjectFileELFTest, GetModuleSpecifications_OffsetSizeWithOffsetFile) { + // The contents of offset-test.bin are + // - 0-1023: \0 + // - 1024-4623: liboffset-test.so (offset: 1024, size: 3600, CRC32: 7D6E4738) + // - 4624-4639: \0 + std::string SO = GetInputFilePath("offset-test.bin"); + ModuleSpecList Specs; + ASSERT_EQ( + 1u, ObjectFile::GetModuleSpecifications(FileSpec(SO), 1024, 3600, Specs)); + ModuleSpec Spec; + ASSERT_TRUE(Specs.GetModuleSpecAtIndex(0, Spec)) ; + UUID Uuid; + Uuid.SetFromStringRef("7D6E4738"); + EXPECT_EQ(Spec.GetUUID(), Uuid); + EXPECT_EQ(Spec.GetObjectOffset(), 1024UL); + EXPECT_EQ(Spec.GetObjectSize(), 3600UL); + EXPECT_EQ(FileSystem::Instance().GetByteSize(FileSpec(SO)), 4640UL); +} + TEST_F(ObjectFileELFTest, GetSymtab_NoSymEntryPointArmThumbAddressClass) { /* // nosym-entrypoint-arm-thumb.s Index: lldb/unittests/ObjectFile/ELF/CMakeLists.txt =================================================================== --- lldb/unittests/ObjectFile/ELF/CMakeLists.txt +++ lldb/unittests/ObjectFile/ELF/CMakeLists.txt @@ -11,5 +11,7 @@ set(test_inputs early-section-headers.so + liboffset-test.so + offset-test.bin ) add_unittest_inputs(ObjectFileELFTests "${test_inputs}") Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -555,6 +555,14 @@ if (header.Parse(data, &header_offset)) { if (data_sp) { ModuleSpec spec(file); + // In Android API level 23 and above, bionic dynamic linker is able to + // load .so file directly from zip file. In that case, .so file is + // page aligned and uncompressed, and this module spec should retain the + // .so file offset and file size to pass through the information from + // lldb-server to LLDB. For normal file, file_offset should be 0, + // length should be the size of the file. + spec.SetObjectOffset(file_offset); + spec.SetObjectSize(length); const uint32_t sub_type = subTypeFromElfHeader(header); spec.GetArchitecture().SetArchitecture( @@ -586,8 +594,12 @@ __FUNCTION__, file.GetPath().c_str()); } + // When ELF file does not contain GNU build ID, the later code will + // calculate CRC32 with this data_sp file_offset and length. It is + // important for Android zip .so file, which is a slice of a file, + // to not access the outside of the file slice range. if (data_sp->GetByteSize() < length) - data_sp = MapFileData(file, -1, file_offset); + data_sp = MapFileData(file, length, file_offset); if (data_sp) data.SetData(data_sp); // In case there is header extension in the section #0, the header we
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits