fun ReadHeader()

in jvm/src/main/kotlin/com/jetbrains/util/filetype/FileTypeDetector.kt [171:222]


      fun ReadHeader(magic: Long): Pair<EnumSet<FileProperties>, List<ProcessorArchitecture>>? {
        // Note: See https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h

        val isLe32 = magic == 0xFEEDFACE // MH_MAGIC
        val isLe64 = magic == 0xFEEDFACF // MH_MAGIC_64
        val isBe32 = magic == 0xCEFAEDFE // MH_CIGAM
        val isBe64 = magic == 0xCFFAEDFE // MH_CIGAM_64

        if (isLe32 || isLe64 || isBe32 || isBe64) {
          // Machine types:
          val CPU_ARCH_ABI64 = 0x01000000
          val CPU_TYPE_X86 = 7
          val CPU_TYPE_X86_64 = CPU_TYPE_X86 or CPU_ARCH_ABI64
          val CPU_TYPE_ARM64 = 12 or CPU_ARCH_ABI64

          val cputype =
            when (reader.ReadUInt32Le(isBe32 || isBe64).toInt())  // mach_header::cputype / mach_header_64::cputype
            {
              CPU_TYPE_X86 -> ProcessorArchitecture.PROCESSOR_ARCHITECTURE_INTEL // CPU_TYPE_X86
              CPU_TYPE_X86_64 -> ProcessorArchitecture.PROCESSOR_ARCHITECTURE_AMD64 // CPU_TYPE_X86_64
              CPU_TYPE_ARM64 -> ProcessorArchitecture.PROCESSOR_ARCHITECTURE_ARM64 // CPU_TYPE_ARM64
              else -> ProcessorArchitecture.PROCESSOR_ARCHITECTURE_UNKNOWN
            }

          stream.Seek(4, SeekOrigin.Current)

          val fileProperties = enumSetOf(
            when (reader.ReadUInt32Le(isBe32 || isBe64).toInt()) // mach_header::filetype / mach_header_64::filetype
            {
              0x2 -> FileProperties.ExecutableType // MH_EXECUTE
              0x6 -> FileProperties.SharedLibraryType // MH_DYLIB
              0x8 -> FileProperties.BundleType // MH_BUNDLE
              else -> FileProperties.UnknownType
            }
          )

          var ncmds = reader.ReadUInt32Le(isBe32 || isBe64).toInt() // mach_header::ncmds / mach_header_64::ncmds
          stream.Seek(if (isLe64 || isBe64) 0xC else 0x8, SeekOrigin.Current) // load_command[0]

          while (ncmds-- > 0) {
            val cmd = reader.ReadUInt32Le(isBe32 || isBe64) // load_command::cmd
            val cmdsize = reader.ReadUInt32Le(isBe32 || isBe64) // load_command::cmdsize
            stream.Seek((cmdsize - 8u).toLong(), SeekOrigin.Current)

            if (cmd == 0x1Du) // LC_CODE_SIGNATURE
              fileProperties += FileProperties.Signed
          }

          return fileProperties to listOf(cputype)
        }
        return null
      }