ELFObjectFile.cpp revision 4d9c5397b4a3be747bdb73f1d24c3fdbaaf438fe
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
14f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky#include "llvm/Object/ELF.h"
154d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer#include "llvm/Support/MathExtras.h"
16b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer
17f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskynamespace llvm {
180fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
19f4eff4baeb44f9dee988e9293d029dcaa359420dEli Benderskyusing namespace object;
200fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
21f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky// Creates an in-memory object-file by default: createELFObjectFile(Buffer)
22f4eff4baeb44f9dee988e9293d029dcaa359420dEli BenderskyObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
23f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  std::pair<unsigned char, unsigned char> Ident = getElfArchType(Object);
24f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  error_code ec;
25bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky
264d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer  std::size_t MaxAlignment =
274d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    1ULL << CountTrailingZeros_64(uintptr_t(Object->getBufferStart()));
284d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer
29f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
304d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 4)
314d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::little, 4, false>(Object, ec);
324d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else if (MaxAlignment >= 2)
334d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::little, 2, false>(Object, ec);
344d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
354d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
36f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
374d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 4)
384d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::big, 4, false>(Object, ec);
394d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else if (MaxAlignment >= 2)
404d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::big, 2, false>(Object, ec);
414d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
424d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
43f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
444d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 8)
454d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::big, 8, true>(Object, ec);
464d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else if (MaxAlignment >= 2)
474d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::big, 2, true>(Object, ec);
484d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
494d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
50f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
514d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    if (MaxAlignment >= 8)
524d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::little, 8, true>(Object, ec);
534d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else if (MaxAlignment >= 2)
544d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      return new ELFObjectFile<support::little, 2, true>(Object, ec);
554d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer    else
564d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer      llvm_unreachable("Invalid alignment for ELF file!");
57bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky  }
584344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer
59f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky  report_fatal_error("Buffer is not an ELF object file!");
600fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer}
610fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer
62b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace llvm
63