1b60a18deSMichael J. Spencer //===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===// 2b60a18deSMichael J. Spencer // 3b60a18deSMichael J. Spencer // The LLVM Compiler Infrastructure 4b60a18deSMichael J. Spencer // 5b60a18deSMichael J. Spencer // This file is distributed under the University of Illinois Open Source 6b60a18deSMichael J. Spencer // License. See LICENSE.TXT for details. 7b60a18deSMichael J. Spencer // 8b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===// 9b60a18deSMichael J. Spencer // 10c7d23ddbSEli Bendersky // Part of the ELFObjectFile class implementation. 11b60a18deSMichael J. Spencer // 12b60a18deSMichael J. Spencer //===----------------------------------------------------------------------===// 13b60a18deSMichael J. Spencer 14126973baSMichael J. Spencer #include "llvm/Object/ELFObjectFile.h" 15bae14cefSMichael J. Spencer #include "llvm/Support/MathExtras.h" 16b60a18deSMichael J. Spencer 17c7d23ddbSEli Bendersky namespace llvm { 18b60a18deSMichael J. Spencer using namespace object; 19b60a18deSMichael J. Spencer 2048af1c2aSRafael Espindola ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source) 2148af1c2aSRafael Espindola : ObjectFile(Type, Source) {} 22ab73774cSRafael Espindola 23437b0d58SRafael Espindola ErrorOr<std::unique_ptr<ObjectFile>> 2448af1c2aSRafael Espindola ObjectFile::createELFObjectFile(MemoryBufferRef Obj) { 25d5a8efe7SRafael Espindola std::pair<unsigned char, unsigned char> Ident = 2648af1c2aSRafael Espindola getElfArchType(Obj.getBuffer()); 27bae14cefSMichael J. Spencer std::size_t MaxAlignment = 2848af1c2aSRafael Espindola 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart())); 29bae14cefSMichael J. Spencer 30ac729b46SRafael Espindola if (MaxAlignment < 2) 31ac729b46SRafael Espindola return object_error::parse_failed; 32ac729b46SRafael Espindola 33db4ed0bdSRafael Espindola std::error_code EC; 3456440fd8SAhmed Charles std::unique_ptr<ObjectFile> R; 35ac729b46SRafael Espindola if (Ident.first == ELF::ELFCLASS32) { 36ac729b46SRafael Espindola if (Ident.second == ELF::ELFDATA2LSB) 37ac729b46SRafael Espindola R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC)); 38ac729b46SRafael Espindola else if (Ident.second == ELF::ELFDATA2MSB) 39ac729b46SRafael Espindola R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC)); 40692410efSRafael Espindola else 4118ad2e54SAlexey Samsonov return object_error::parse_failed; 4249179ddbSAlexey Samsonov } else if (Ident.first == ELF::ELFCLASS64) { 43ac729b46SRafael Espindola if (Ident.second == ELF::ELFDATA2LSB) 44ac729b46SRafael Espindola R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC)); 45ac729b46SRafael Espindola else if (Ident.second == ELF::ELFDATA2MSB) 46ac729b46SRafael Espindola R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC)); 47ac729b46SRafael Espindola else 4818ad2e54SAlexey Samsonov return object_error::parse_failed; 4949179ddbSAlexey Samsonov } else { 5049179ddbSAlexey Samsonov return object_error::parse_failed; 51ac729b46SRafael Espindola } 52692410efSRafael Espindola 53692410efSRafael Espindola if (EC) 54692410efSRafael Espindola return EC; 55437b0d58SRafael Espindola return std::move(R); 56b60a18deSMichael J. Spencer } 57b60a18deSMichael J. Spencer 581d14864bSDaniel Sanders SubtargetFeatures ELFObjectFileBase::getFeatures() const { 591d14864bSDaniel Sanders switch (getEMachine()) { 601d14864bSDaniel Sanders case ELF::EM_MIPS: { 611d14864bSDaniel Sanders SubtargetFeatures Features; 621d14864bSDaniel Sanders unsigned PlatformFlags; 631d14864bSDaniel Sanders getPlatformFlags(PlatformFlags); 641d14864bSDaniel Sanders 651d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 661d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_1: 671d14864bSDaniel Sanders break; 681d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_2: 691d14864bSDaniel Sanders Features.AddFeature("mips2"); 701d14864bSDaniel Sanders break; 711d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_3: 721d14864bSDaniel Sanders Features.AddFeature("mips3"); 731d14864bSDaniel Sanders break; 741d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_4: 751d14864bSDaniel Sanders Features.AddFeature("mips4"); 761d14864bSDaniel Sanders break; 771d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_5: 781d14864bSDaniel Sanders Features.AddFeature("mips5"); 791d14864bSDaniel Sanders break; 801d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32: 811d14864bSDaniel Sanders Features.AddFeature("mips32"); 821d14864bSDaniel Sanders break; 831d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64: 841d14864bSDaniel Sanders Features.AddFeature("mips64"); 851d14864bSDaniel Sanders break; 861d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R2: 871d14864bSDaniel Sanders Features.AddFeature("mips32r2"); 881d14864bSDaniel Sanders break; 891d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R2: 901d14864bSDaniel Sanders Features.AddFeature("mips64r2"); 911d14864bSDaniel Sanders break; 921d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R6: 931d14864bSDaniel Sanders Features.AddFeature("mips32r6"); 941d14864bSDaniel Sanders break; 951d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R6: 961d14864bSDaniel Sanders Features.AddFeature("mips64r6"); 971d14864bSDaniel Sanders break; 981d14864bSDaniel Sanders default: 991d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1001d14864bSDaniel Sanders } 1011d14864bSDaniel Sanders 1021d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_MACH) { 1031d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_NONE: 1041d14864bSDaniel Sanders // No feature associated with this value. 1051d14864bSDaniel Sanders break; 1061d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_OCTEON: 1071d14864bSDaniel Sanders Features.AddFeature("cnmips"); 1081d14864bSDaniel Sanders break; 1091d14864bSDaniel Sanders default: 1101d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 1111d14864bSDaniel Sanders } 1121d14864bSDaniel Sanders 1131d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 1141d14864bSDaniel Sanders Features.AddFeature("mips16"); 1151d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 1161d14864bSDaniel Sanders Features.AddFeature("micromips"); 1171d14864bSDaniel Sanders 1181d14864bSDaniel Sanders return Features; 1191d14864bSDaniel Sanders } 1201d14864bSDaniel Sanders default: 1211d14864bSDaniel Sanders return SubtargetFeatures(); 1221d14864bSDaniel Sanders } 1231d14864bSDaniel Sanders } 1241d14864bSDaniel Sanders 125*df7c6ef9SSam Parker // FIXME Encode from a tablegen description or target parser. 126*df7c6ef9SSam Parker void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { 127*df7c6ef9SSam Parker if (TheTriple.getSubArch() != Triple::NoSubArch) 128*df7c6ef9SSam Parker return; 129*df7c6ef9SSam Parker 130*df7c6ef9SSam Parker ARMAttributeParser Attributes; 131*df7c6ef9SSam Parker std::error_code EC = getBuildAttributes(Attributes); 132*df7c6ef9SSam Parker if (EC) 133*df7c6ef9SSam Parker return; 134*df7c6ef9SSam Parker 135*df7c6ef9SSam Parker std::string Triple; 136*df7c6ef9SSam Parker // Default to ARM, but use the triple if it's been set. 137*df7c6ef9SSam Parker if (TheTriple.getArch() == Triple::thumb || 138*df7c6ef9SSam Parker TheTriple.getArch() == Triple::thumbeb) 139*df7c6ef9SSam Parker Triple = "thumb"; 140*df7c6ef9SSam Parker else 141*df7c6ef9SSam Parker Triple = "arm"; 142*df7c6ef9SSam Parker 143*df7c6ef9SSam Parker if (Attributes.hasAttribute(ARMBuildAttrs::CPU_arch)) { 144*df7c6ef9SSam Parker switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) { 145*df7c6ef9SSam Parker case ARMBuildAttrs::v4: 146*df7c6ef9SSam Parker Triple += "v4"; 147*df7c6ef9SSam Parker break; 148*df7c6ef9SSam Parker case ARMBuildAttrs::v4T: 149*df7c6ef9SSam Parker Triple += "v4t"; 150*df7c6ef9SSam Parker break; 151*df7c6ef9SSam Parker case ARMBuildAttrs::v5T: 152*df7c6ef9SSam Parker Triple += "v5t"; 153*df7c6ef9SSam Parker break; 154*df7c6ef9SSam Parker case ARMBuildAttrs::v5TE: 155*df7c6ef9SSam Parker Triple += "v5te"; 156*df7c6ef9SSam Parker break; 157*df7c6ef9SSam Parker case ARMBuildAttrs::v5TEJ: 158*df7c6ef9SSam Parker Triple += "v5tej"; 159*df7c6ef9SSam Parker break; 160*df7c6ef9SSam Parker case ARMBuildAttrs::v6: 161*df7c6ef9SSam Parker Triple += "v6"; 162*df7c6ef9SSam Parker break; 163*df7c6ef9SSam Parker case ARMBuildAttrs::v6KZ: 164*df7c6ef9SSam Parker Triple += "v6kz"; 165*df7c6ef9SSam Parker break; 166*df7c6ef9SSam Parker case ARMBuildAttrs::v6T2: 167*df7c6ef9SSam Parker Triple += "v6t2"; 168*df7c6ef9SSam Parker break; 169*df7c6ef9SSam Parker case ARMBuildAttrs::v6K: 170*df7c6ef9SSam Parker Triple += "v6k"; 171*df7c6ef9SSam Parker break; 172*df7c6ef9SSam Parker case ARMBuildAttrs::v7: 173*df7c6ef9SSam Parker Triple += "v7"; 174*df7c6ef9SSam Parker break; 175*df7c6ef9SSam Parker case ARMBuildAttrs::v6_M: 176*df7c6ef9SSam Parker Triple += "v6m"; 177*df7c6ef9SSam Parker break; 178*df7c6ef9SSam Parker case ARMBuildAttrs::v6S_M: 179*df7c6ef9SSam Parker Triple += "v6sm"; 180*df7c6ef9SSam Parker break; 181*df7c6ef9SSam Parker case ARMBuildAttrs::v7E_M: 182*df7c6ef9SSam Parker Triple += "v7em"; 183*df7c6ef9SSam Parker break; 184*df7c6ef9SSam Parker } 185*df7c6ef9SSam Parker } 186*df7c6ef9SSam Parker if (!isLittleEndian()) 187*df7c6ef9SSam Parker Triple += "eb"; 188*df7c6ef9SSam Parker 189*df7c6ef9SSam Parker TheTriple.setArchName(Triple); 190*df7c6ef9SSam Parker } 191*df7c6ef9SSam Parker 192b60a18deSMichael J. Spencer } // end namespace llvm 193