ELFObjectFile.cpp revision 081a1941b595f6294e4ce678fd61ef56a2ceb51e
1b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
3b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//                     The LLVM Compiler Infrastructure
4b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
5b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// This file is distributed under the University of Illinois Open Source
6b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer// License. See LICENSE.TXT for details.
7b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
8b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//===----------------------------------------------------------------------===//
9b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
10f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Part of the ELFObjectFile class implementation.
11b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//
12b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer//===----------------------------------------------------------------------===//
13b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
14081a1941b595f6294e4ce678fd61ef56a2ceb51eMichael J. Spencer#include "llvm/Object/ELFObjectFile.h"
154d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer#include "llvm/Support/MathExtras.h"
16b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
17f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskynamespace llvm {
18f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyusing namespace object;
190fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
20f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Creates an in-memory object-file by default: createELFObjectFile(Buffer)
21f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
22f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
23f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  error_code ec;
24bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky
254d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer  std::size_t MaxAlignment =
26c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer    1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart()));
274d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer
28f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
29d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST
304d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 4)
31ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::little, 4, false> >(Object, ec);
32d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    else
33d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif
34d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    if (MaxAlignment >= 2)
35ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::little, 2, false> >(Object, ec);
364d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
374d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
38f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
39d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST
404d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 4)
41ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::big, 4, false> >(Object, ec);
42d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    else
43d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif
44d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    if (MaxAlignment >= 2)
45ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::big, 2, false> >(Object, ec);
464d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
474d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
48f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
49d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST
504d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 8)
51ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::big, 8, true> >(Object, ec);
52d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    else
53d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif
54d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    if (MaxAlignment >= 2)
55ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::big, 2, true> >(Object, ec);
564d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
574d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
58f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
59d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST
604d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 8)
61ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::little, 8, true> >(Object, ec);
62d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    else
63d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif
64d9d2f187759d0154574657c195068d367c338473Michael J. Spencer    if (MaxAlignment >= 2)
65ac97f5ce486d1ca2967607028eacddd860aaddd0Michael J. Spencer      return new ELFObjectFile<ELFType<support::little, 2, true> >(Object, ec);
664d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
674d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
68bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  }
694344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
70f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  report_fatal_error("Buffer is not an ELF object file!");
710fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
720fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
73b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace llvm
74