LLVM API Documentation

ELFObjectFile.cpp
Go to the documentation of this file.
00001 //===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Part of the ELFObjectFile class implementation.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Object/ELFObjectFile.h"
00015 #include "llvm/Support/MathExtras.h"
00016 
00017 namespace llvm {
00018 using namespace object;
00019 
00020 ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
00021     : ObjectFile(Type, Source) {}
00022 
00023 ErrorOr<std::unique_ptr<ObjectFile>>
00024 ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
00025   std::pair<unsigned char, unsigned char> Ident =
00026       getElfArchType(Obj.getBuffer());
00027   std::size_t MaxAlignment =
00028       1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
00029 
00030   std::error_code EC;
00031   std::unique_ptr<ObjectFile> R;
00032   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
00033 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
00034     if (MaxAlignment >= 4)
00035       R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>(Obj, EC));
00036     else
00037 #endif
00038     if (MaxAlignment >= 2)
00039       R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>(Obj, EC));
00040     else
00041       return object_error::parse_failed;
00042   else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
00043 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
00044     if (MaxAlignment >= 4)
00045       R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(Obj, EC));
00046     else
00047 #endif
00048     if (MaxAlignment >= 2)
00049       R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(Obj, EC));
00050     else
00051       return object_error::parse_failed;
00052   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
00053 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
00054     if (MaxAlignment >= 8)
00055       R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(Obj, EC));
00056     else
00057 #endif
00058     if (MaxAlignment >= 2)
00059       R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(Obj, EC));
00060     else
00061       return object_error::parse_failed;
00062   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
00063 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
00064     if (MaxAlignment >= 8)
00065       R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>(Obj, EC));
00066     else
00067 #endif
00068     if (MaxAlignment >= 2)
00069       R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>(Obj, EC));
00070     else
00071       return object_error::parse_failed;
00072   }
00073   else
00074     llvm_unreachable("Buffer is not an ELF object file!");
00075 
00076   if (EC)
00077     return EC;
00078   return std::move(R);
00079 }
00080 
00081 } // end namespace llvm