forked from OSchip/llvm-project
110 lines
3.5 KiB
C++
110 lines
3.5 KiB
C++
//===-- llvm/BinaryFormat/MachO.cpp - The MachO file format -----*- C++/-*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/BinaryFormat/MachO.h"
|
|
#include "llvm/ADT/Triple.h"
|
|
#include "llvm/Support/ARMTargetParser.h"
|
|
|
|
using namespace llvm;
|
|
|
|
static MachO::CPUSubTypeX86 getX86SubType(const Triple &T) {
|
|
assert(T.isX86());
|
|
if (T.isArch32Bit())
|
|
return MachO::CPU_SUBTYPE_I386_ALL;
|
|
|
|
assert(T.isArch64Bit());
|
|
if (T.getArchName() == "x86_64h")
|
|
return MachO::CPU_SUBTYPE_X86_64_H;
|
|
return MachO::CPU_SUBTYPE_X86_64_ALL;
|
|
}
|
|
|
|
static MachO::CPUSubTypeARM getARMSubType(const Triple &T) {
|
|
assert(T.isARM() || T.isThumb());
|
|
StringRef Arch = T.getArchName();
|
|
ARM::ArchKind AK = ARM::parseArch(Arch);
|
|
switch (AK) {
|
|
default:
|
|
return MachO::CPU_SUBTYPE_ARM_V7;
|
|
case ARM::ArchKind::ARMV4T:
|
|
return MachO::CPU_SUBTYPE_ARM_V4T;
|
|
case ARM::ArchKind::ARMV5T:
|
|
case ARM::ArchKind::ARMV5TE:
|
|
case ARM::ArchKind::ARMV5TEJ:
|
|
return MachO::CPU_SUBTYPE_ARM_V5;
|
|
case ARM::ArchKind::ARMV6:
|
|
case ARM::ArchKind::ARMV6K:
|
|
return MachO::CPU_SUBTYPE_ARM_V6;
|
|
case ARM::ArchKind::ARMV7A:
|
|
return MachO::CPU_SUBTYPE_ARM_V7;
|
|
case ARM::ArchKind::ARMV7S:
|
|
return MachO::CPU_SUBTYPE_ARM_V7S;
|
|
case ARM::ArchKind::ARMV7K:
|
|
return MachO::CPU_SUBTYPE_ARM_V7K;
|
|
case ARM::ArchKind::ARMV6M:
|
|
return MachO::CPU_SUBTYPE_ARM_V6M;
|
|
case ARM::ArchKind::ARMV7M:
|
|
return MachO::CPU_SUBTYPE_ARM_V7M;
|
|
case ARM::ArchKind::ARMV7EM:
|
|
return MachO::CPU_SUBTYPE_ARM_V7EM;
|
|
}
|
|
}
|
|
|
|
static MachO::CPUSubTypeARM64 getARM64SubType(const Triple &T) {
|
|
assert(T.isAArch64() || T.getArch() == Triple::aarch64_32);
|
|
if (T.isArch32Bit())
|
|
return (MachO::CPUSubTypeARM64)MachO::CPU_SUBTYPE_ARM64_32_V8;
|
|
if (T.getArchName() == "arm64e")
|
|
return MachO::CPU_SUBTYPE_ARM64E;
|
|
|
|
return MachO::CPU_SUBTYPE_ARM64_ALL;
|
|
}
|
|
|
|
static MachO::CPUSubTypePowerPC getPowerPCSubType(const Triple &T) {
|
|
return MachO::CPU_SUBTYPE_POWERPC_ALL;
|
|
}
|
|
|
|
static Error unsupported(const char *Str, const Triple &T) {
|
|
return createStringError(std::errc::invalid_argument,
|
|
"Unsupported triple for mach-o cpu %s: %s", Str,
|
|
T.str().c_str());
|
|
}
|
|
|
|
Expected<uint32_t> MachO::getCPUType(const Triple &T) {
|
|
if (!T.isOSBinFormatMachO())
|
|
return unsupported("type", T);
|
|
if (T.isX86() && T.isArch32Bit())
|
|
return MachO::CPU_TYPE_X86;
|
|
if (T.isX86() && T.isArch64Bit())
|
|
return MachO::CPU_TYPE_X86_64;
|
|
if (T.isARM() || T.isThumb())
|
|
return MachO::CPU_TYPE_ARM;
|
|
if (T.isAArch64())
|
|
return MachO::CPU_TYPE_ARM64;
|
|
if (T.getArch() == Triple::aarch64_32)
|
|
return MachO::CPU_TYPE_ARM64_32;
|
|
if (T.getArch() == Triple::ppc)
|
|
return MachO::CPU_TYPE_POWERPC;
|
|
if (T.getArch() == Triple::ppc64)
|
|
return MachO::CPU_TYPE_POWERPC64;
|
|
return unsupported("type", T);
|
|
}
|
|
|
|
Expected<uint32_t> MachO::getCPUSubType(const Triple &T) {
|
|
if (!T.isOSBinFormatMachO())
|
|
return unsupported("subtype", T);
|
|
if (T.isX86())
|
|
return getX86SubType(T);
|
|
if (T.isARM() || T.isThumb())
|
|
return getARMSubType(T);
|
|
if (T.isAArch64() || T.getArch() == Triple::aarch64_32)
|
|
return getARM64SubType(T);
|
|
if (T.getArch() == Triple::ppc || T.getArch() == Triple::ppc64)
|
|
return getPowerPCSubType(T);
|
|
return unsupported("subtype", T);
|
|
}
|