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 58*1d14864bSDaniel Sanders SubtargetFeatures ELFObjectFileBase::getFeatures() const { 59*1d14864bSDaniel Sanders switch (getEMachine()) { 60*1d14864bSDaniel Sanders case ELF::EM_MIPS: { 61*1d14864bSDaniel Sanders SubtargetFeatures Features; 62*1d14864bSDaniel Sanders unsigned PlatformFlags; 63*1d14864bSDaniel Sanders getPlatformFlags(PlatformFlags); 64*1d14864bSDaniel Sanders 65*1d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_ARCH) { 66*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_1: 67*1d14864bSDaniel Sanders break; 68*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_2: 69*1d14864bSDaniel Sanders Features.AddFeature("mips2"); 70*1d14864bSDaniel Sanders break; 71*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_3: 72*1d14864bSDaniel Sanders Features.AddFeature("mips3"); 73*1d14864bSDaniel Sanders break; 74*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_4: 75*1d14864bSDaniel Sanders Features.AddFeature("mips4"); 76*1d14864bSDaniel Sanders break; 77*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_5: 78*1d14864bSDaniel Sanders Features.AddFeature("mips5"); 79*1d14864bSDaniel Sanders break; 80*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32: 81*1d14864bSDaniel Sanders Features.AddFeature("mips32"); 82*1d14864bSDaniel Sanders break; 83*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64: 84*1d14864bSDaniel Sanders Features.AddFeature("mips64"); 85*1d14864bSDaniel Sanders break; 86*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R2: 87*1d14864bSDaniel Sanders Features.AddFeature("mips32r2"); 88*1d14864bSDaniel Sanders break; 89*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R2: 90*1d14864bSDaniel Sanders Features.AddFeature("mips64r2"); 91*1d14864bSDaniel Sanders break; 92*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_32R6: 93*1d14864bSDaniel Sanders Features.AddFeature("mips32r6"); 94*1d14864bSDaniel Sanders break; 95*1d14864bSDaniel Sanders case ELF::EF_MIPS_ARCH_64R6: 96*1d14864bSDaniel Sanders Features.AddFeature("mips64r6"); 97*1d14864bSDaniel Sanders break; 98*1d14864bSDaniel Sanders default: 99*1d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 100*1d14864bSDaniel Sanders } 101*1d14864bSDaniel Sanders 102*1d14864bSDaniel Sanders switch (PlatformFlags & ELF::EF_MIPS_MACH) { 103*1d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_NONE: 104*1d14864bSDaniel Sanders // No feature associated with this value. 105*1d14864bSDaniel Sanders break; 106*1d14864bSDaniel Sanders case ELF::EF_MIPS_MACH_OCTEON: 107*1d14864bSDaniel Sanders Features.AddFeature("cnmips"); 108*1d14864bSDaniel Sanders break; 109*1d14864bSDaniel Sanders default: 110*1d14864bSDaniel Sanders llvm_unreachable("Unknown EF_MIPS_ARCH value"); 111*1d14864bSDaniel Sanders } 112*1d14864bSDaniel Sanders 113*1d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_ARCH_ASE_M16) 114*1d14864bSDaniel Sanders Features.AddFeature("mips16"); 115*1d14864bSDaniel Sanders if (PlatformFlags & ELF::EF_MIPS_MICROMIPS) 116*1d14864bSDaniel Sanders Features.AddFeature("micromips"); 117*1d14864bSDaniel Sanders 118*1d14864bSDaniel Sanders return Features; 119*1d14864bSDaniel Sanders } 120*1d14864bSDaniel Sanders default: 121*1d14864bSDaniel Sanders return SubtargetFeatures(); 122*1d14864bSDaniel Sanders } 123*1d14864bSDaniel Sanders } 124*1d14864bSDaniel Sanders 125b60a18deSMichael J. Spencer } // end namespace llvm 126