Skip to content

Commit 62c42ed

Browse files
authored
Merge pull request #295 from p-x9/codex/optimize-segment-lookups
Avoid segment array allocation in address lookups
2 parents 6f47729 + d3916ce commit 62c42ed

2 files changed

Lines changed: 37 additions & 11 deletions

File tree

Sources/MachOKit/MachOFile.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -885,13 +885,26 @@ extension MachOFile {
885885
if let cache {
886886
return cache.fileOffset(of: vmaddr)
887887
}
888-
for segment in self.segments {
889-
if segment.virtualMemoryAddress <= vmaddr,
890-
vmaddr < segment.virtualMemoryAddress + segment.virtualMemorySize {
891-
return vmaddr + numericCast(segment.fileOffset) - numericCast(segment.virtualMemoryAddress)
888+
if is64Bit {
889+
return _fileOffset(of: vmaddr, in: segments64)
890+
} else {
891+
return _fileOffset(of: vmaddr, in: segments32)
892+
}
893+
}
894+
895+
@inline(__always)
896+
private func _fileOffset<Segments: Sequence>(
897+
of vmaddr: UInt64,
898+
in segments: Segments
899+
) -> UInt64? where Segments.Element: SegmentCommandProtocol {
900+
for segment in segments {
901+
let segmentVMAddr = UInt64(segment.virtualMemoryAddress)
902+
if segmentVMAddr <= vmaddr,
903+
vmaddr < segmentVMAddr + UInt64(segment.virtualMemorySize) {
904+
return vmaddr + UInt64(segment.fileOffset) - segmentVMAddr
892905
}
893-
if segment.segmentName == SEG_TEXT,
894-
vmaddr < segment.virtualMemoryAddress {
906+
if vmaddr < segmentVMAddr,
907+
segment.segmentName == SEG_TEXT {
895908
return vmaddr
896909
}
897910
}

Sources/MachOKit/Protocol/MachORepresentable.swift

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -963,12 +963,25 @@ extension MachORepresentable where IndirectSymbols.Index == Int {
963963

964964
extension MachORepresentable {
965965
public func contains(unslidAddress address: UInt64) -> Bool {
966-
segments.contains(
967-
where: {
968-
$0.contains(unslidAddress: address)
969-
}
970-
)
966+
if is64Bit {
967+
_contains(unslidAddress: address, in: segments64)
968+
} else {
969+
_contains(unslidAddress: address, in: segments32)
970+
}
971+
}
972+
}
973+
974+
@inline(__always)
975+
private func _contains<Segments: Sequence>(
976+
unslidAddress address: UInt64,
977+
in segments: Segments
978+
) -> Bool where Segments.Element: SegmentCommandProtocol {
979+
for segment in segments {
980+
if segment.contains(unslidAddress: address) {
981+
return true
982+
}
971983
}
984+
return false
972985
}
973986

974987
extension MachORepresentable {

0 commit comments

Comments
 (0)