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 
14c7d23ddbSEli Bendersky #include "llvm/Object/ELF.h"
15bae14cefSMichael J. Spencer #include "llvm/Support/MathExtras.h"
16b60a18deSMichael J. Spencer 
17c7d23ddbSEli Bendersky namespace llvm {
18c7d23ddbSEli Bendersky 
19b60a18deSMichael J. Spencer using namespace object;
20b60a18deSMichael J. Spencer 
21c3c80f09SEli Bendersky // Creates an in-memory object-file by default: createELFObjectFile(Buffer)
22c7d23ddbSEli Bendersky ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
23b60a18deSMichael J. Spencer   std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
24ec29b121SMichael J. Spencer   error_code ec;
25c3c80f09SEli Bendersky 
26bae14cefSMichael J. Spencer   std::size_t MaxAlignment =
27*df1ecbd7SMichael J. Spencer     1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart()));
28bae14cefSMichael J. Spencer 
29b60a18deSMichael J. Spencer   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
3039678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
31bae14cefSMichael J. Spencer     if (MaxAlignment >= 4)
321a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
3339678d83SMichael J. Spencer     else
3439678d83SMichael J. Spencer #endif
3539678d83SMichael J. Spencer     if (MaxAlignment >= 2)
361a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
37bae14cefSMichael J. Spencer     else
38bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
39b60a18deSMichael J. Spencer   else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
4039678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
41bae14cefSMichael J. Spencer     if (MaxAlignment >= 4)
421a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
4339678d83SMichael J. Spencer     else
4439678d83SMichael J. Spencer #endif
4539678d83SMichael J. Spencer     if (MaxAlignment >= 2)
461a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
47bae14cefSMichael J. Spencer     else
48bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
49b60a18deSMichael J. Spencer   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
5039678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
51bae14cefSMichael J. Spencer     if (MaxAlignment >= 8)
521a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
5339678d83SMichael J. Spencer     else
5439678d83SMichael J. Spencer #endif
5539678d83SMichael J. Spencer     if (MaxAlignment >= 2)
561a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
57bae14cefSMichael J. Spencer     else
58bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
59c3c80f09SEli Bendersky   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
6039678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
61bae14cefSMichael J. Spencer     if (MaxAlignment >= 8)
621a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
6339678d83SMichael J. Spencer     else
6439678d83SMichael J. Spencer #endif
6539678d83SMichael J. Spencer     if (MaxAlignment >= 2)
661a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
67bae14cefSMichael J. Spencer     else
68bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
69c3c80f09SEli Bendersky   }
70c3c80f09SEli Bendersky 
71c3c80f09SEli Bendersky   report_fatal_error("Buffer is not an ELF object file!");
72b60a18deSMichael J. Spencer }
73b60a18deSMichael J. Spencer 
74b60a18deSMichael J. Spencer } // end namespace llvm
75