This is an archive of the discontinued LLVM Phabricator instance.

[lldb][ObjectFileELF] Set ModuleSpec file offset and size
ClosedPublic

Authored by splhack on Jun 12 2023, 4:36 PM.

Details

Summary

In Android API level 23 and above, dynamic loader is able to load .so file
directly from APK.
https://android.googlesource.com/platform/bionic/+/master/
android-changes-for-ndk-developers.md#
opening-shared-libraries-directly-from-an-apk

ObjectFileELF::GetModuleSpecifications will load a .so file, which is page
aligned and uncompressed, directly from a zip file. However it does not
set the .so file offset and size to the ModuleSpec. Also crc32 calculation
uses more data than the .so file size.

Set the .so file offset and size to the ModuleSpec, and set the size to
MapFileData length argument. For normal file, file_offset should be zero,
and length should be the size of the file.

Diff Detail

Event Timeline

splhack created this revision.Jun 12 2023, 4:36 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 12 2023, 4:36 PM
Herald added a subscriber: emaste. · View Herald Transcript
splhack published this revision for review.Jun 12 2023, 4:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 12 2023, 4:50 PM
splhack updated this revision to Diff 531118.Jun 13 2023, 5:07 PM

clang-format

splhack updated this revision to Diff 531147.Jun 13 2023, 7:07 PM

fix EXPECT_EQ warnings

bulbazord added inline comments.
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
602

A length of -1 means "map the whole file", if my understanding is correct. Why do we want to change this to length instead of just -1? Or is this file the entire zip file?

splhack added inline comments.Jun 15 2023, 2:01 PM
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
602

I'm now updating this diff to add comments to clarify the intention.

For Android zip .so file (D152759),
the ModuleSpec spec will have these info with this diff.

  • object offset = .so file offset inside the zip file
  • object size = .so file size

PlatformAndroid requires this module spec to call DownloadModuleSlice in order to download the .so file from the zip file using adb shell dd.

  • file spec = "zip_path!/lib_path"
  • file offset = .so file offset inside the zip file == dd skip parameter
  • file size = .so file size == dd count parameter

And ObjectFileELF will calculate CRC32 if the ELF does not have GNU BuildID, that will use the data_sp size. Which is set by MapFileData. Currently -1 == the whole zip file size. (In fact, lldb-server is crashing due to SIGSEGV.) It is supposed to be the .so file size.
In the unittest, the test .so file has CRC32 7D6E4738. And it should be the same for the file size.

offset-test.bin contains
-1024bytes of '\0'

  • liboffset-test.so (file offset = 1024, file size = 3600, CRC32 '7D6E4738')
  • 16bytes of '\0'
kusmour added inline comments.
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
602

Reading from Opening shared libraries directly from an APK
Because the .so file is now page aligned and has offset, the actual size should <= the size of file

LGTM. Anyone else have any comments?

splhack updated this revision to Diff 531950.Jun 15 2023, 5:14 PM

add comments

splhack updated this revision to Diff 531954.Jun 15 2023, 5:29 PM

added non zip .so file (normal file) case to the comment

splhack updated this revision to Diff 531990.Jun 15 2023, 10:52 PM

fixed typo and rebase onto D153102

kusmour accepted this revision.Jun 20 2023, 10:34 AM
This revision is now accepted and ready to land.Jun 20 2023, 10:34 AM
clayborg accepted this revision.Jun 20 2023, 2:06 PM
This revision was automatically updated to reflect the committed changes.