in jvm/src/main/kotlin/com/jetbrains/util/filetype/FileTypeDetector.kt [224:294]
fun ReadFatHeader(magic: Long): Pair<EnumSet<FileProperties>, List<ProcessorArchitecture>>? {
// Note: See https://opensource.apple.com/source/xnu/xnu-344/EXTERNAL_HEADERS/mach-o/fat.h
val isLe32 = magic == 0xCAFEBABE // FAT_MAGIC
val isLe64 = magic == 0xCAFEBABF // FAT_MAGIC_64
val isBe32 = magic == 0xBEBAFECA // FAT_CIGAM
val isBe64 = magic == 0xBFBAFECA // FAT_CIGAM_64
if (isLe32 || isLe64 || isBe32 || isBe64) {
var nFatArch = reader.ReadUInt32Le(isBe32 || isBe64).toInt() // fat_header ::nfat_arch
val offsets = mutableListOf<ULong>()
if (isBe64 || isLe64)
while (nFatArch-- > 0) {
stream.Seek(8, SeekOrigin.Current)
offsets.add(reader.ReadUInt64Le(isBe64)) // fat_arch_64::offset
stream.Seek(16, SeekOrigin.Current)
}
else
while (nFatArch-- > 0) {
stream.Seek(8, SeekOrigin.Current)
offsets.add(reader.ReadUInt32Le(isBe32).toULong()) // fat_arch::offset
stream.Seek(8, SeekOrigin.Current)
}
val fileArchitecturesList = mutableListOf<ProcessorArchitecture>()
val filePropertiesList = offsets.map { offset ->
stream.Seek(offset.toLong(), SeekOrigin.Begin)
val fileProperties = ReadHeader(reader.ReadUInt32().toLong()) // mach_header::magic / mach_header64::magic
if (fileProperties != null)
fileArchitecturesList.add(fileProperties.second[0])
fileProperties?.first
}
if (filePropertiesList.isEmpty())
return enumSetOf(FileProperties.UnknownType) to listOf()
// One of headers is invalid
if (filePropertiesList.any { x -> x == null })
return null
val signed = filePropertiesList.all {
it != null && it.contains(FileProperties.Signed)
}
if (filePropertiesList.asSequence().filterNotNull().map {
if (signed) it else {
// One binary in MultiArch file is not signed
it - FileProperties.Signed
}
}.distinct().count() > 1
) {
// Headers are incompatible
return null
}
val totalFileProperty = filePropertiesList[0]
if (filePropertiesList.count() > 1)
if (totalFileProperty != null) {
totalFileProperty += FileProperties.MultiArch
if (!signed) {
totalFileProperty -= FileProperties.Signed
}
}
return totalFileProperty!! to fileArchitecturesList
}
return null
}