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 
14*126973baSMichael 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 
20c3c80f09SEli Bendersky // Creates an in-memory object-file by default: createELFObjectFile(Buffer)
21c7d23ddbSEli Bendersky ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
22b60a18deSMichael J. Spencer   std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
23ec29b121SMichael J. Spencer   error_code ec;
24c3c80f09SEli Bendersky 
25bae14cefSMichael J. Spencer   std::size_t MaxAlignment =
26df1ecbd7SMichael J. Spencer     1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart()));
27bae14cefSMichael J. Spencer 
28b60a18deSMichael J. Spencer   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
2939678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
30bae14cefSMichael J. Spencer     if (MaxAlignment >= 4)
311a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
3239678d83SMichael J. Spencer     else
3339678d83SMichael J. Spencer #endif
3439678d83SMichael J. Spencer     if (MaxAlignment >= 2)
351a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
36bae14cefSMichael J. Spencer     else
37bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
38b60a18deSMichael J. Spencer   else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
3939678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
40bae14cefSMichael J. Spencer     if (MaxAlignment >= 4)
411a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
4239678d83SMichael J. Spencer     else
4339678d83SMichael J. Spencer #endif
4439678d83SMichael J. Spencer     if (MaxAlignment >= 2)
451a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
46bae14cefSMichael J. Spencer     else
47bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
48b60a18deSMichael J. Spencer   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
4939678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
50bae14cefSMichael J. Spencer     if (MaxAlignment >= 8)
511a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
5239678d83SMichael J. Spencer     else
5339678d83SMichael J. Spencer #endif
5439678d83SMichael J. Spencer     if (MaxAlignment >= 2)
551a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
56bae14cefSMichael J. Spencer     else
57bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
58c3c80f09SEli Bendersky   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
5939678d83SMichael J. Spencer #if !LLVM_IS_UNALIGNED_ACCESS_FAST
60bae14cefSMichael J. Spencer     if (MaxAlignment >= 8)
611a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
6239678d83SMichael J. Spencer     else
6339678d83SMichael J. Spencer #endif
6439678d83SMichael J. Spencer     if (MaxAlignment >= 2)
651a79161fSMichael J. Spencer       return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
66bae14cefSMichael J. Spencer     else
67bae14cefSMichael J. Spencer       llvm_unreachable("Invalid alignment for ELF file!");
68c3c80f09SEli Bendersky   }
69c3c80f09SEli Bendersky 
70c3c80f09SEli Bendersky   report_fatal_error("Buffer is not an ELF object file!");
71b60a18deSMichael J. Spencer }
72b60a18deSMichael J. Spencer 
73b60a18deSMichael J. Spencer } // end namespace llvm
74