Skip to content

Commit e2b5baf

Browse files
authored
Merge pull request #234 from p-x9/feature/optimize-linkedit-reading
2 parents 954f8ad + 4064ce8 commit e2b5baf

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

Sources/MachOKit/MachOFile.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -631,19 +631,30 @@ extension MachOFile {
631631
offset: Int, // linkedit_data_command->dataoff (linkedit.fileoff + x)
632632
length: Int
633633
) -> File.FileSlice? {
634+
let text: (any SegmentCommandProtocol)? = loadCommands.text64 ?? loadCommands.text
634635
let linkedit: (any SegmentCommandProtocol)? = loadCommands.linkedit64 ?? loadCommands.linkedit
635-
guard let linkedit else { return nil }
636+
guard let text, let linkedit else { return nil }
636637
guard linkedit.fileOffset + linkedit.fileSize >= offset + length else { return nil }
637638

639+
let maxFileOffsetToCheck = text.fileOffset + linkedit.virtualMemoryAddress - text.virtualMemoryAddress
640+
let isWithinFileRange: Bool = fileHandle.size >= maxFileOffsetToCheck
641+
642+
// 1) text.vmaddr < linkedit.vmaddr
643+
// 2) fileoff_diff <= vmaddr_diff
644+
// 3) If both exist in the same file
645+
// text.fileoff < linkedit.fileoff <= text.fileoff + vmaddr_diff
646+
// 4) if fileHandle.size < text.fileoff + vmaddr_diff
647+
// both exist in the same file
648+
638649
// The linkeditdata in iOS is stored together in a separate, independent cache.
639650
// (.0x.linkeditdata)
640-
if isLoadedFromDyldCache {
651+
if isLoadedFromDyldCache && !isWithinFileRange {
641652
let offset = offset - numericCast(linkedit.fileOffset)
642653
guard let fullCache = self.fullCache,
643654
let fileOffset = fullCache.fileOffset(
644655
of: numericCast(linkedit.virtualMemoryAddress + offset)
645656
),
646-
let (_, segment) = fullCache.urlAndFileSegment(
657+
let segment = fullCache.fileSegment(
647658
forOffset: fileOffset
648659
) else {
649660
return nil

0 commit comments

Comments
 (0)