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 20cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesErrorOr<ObjectFile *> 21cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesObjectFile::createELFObjectFile(std::unique_ptr<MemoryBuffer> &Obj) { 22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::pair<unsigned char, unsigned char> Ident = 23cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getElfArchType(Obj->getBuffer()); 244d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer std::size_t MaxAlignment = 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart())); 264d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer 27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::error_code EC; 2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ObjectFile> R; 29f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) 30d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST 314d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer if (MaxAlignment >= 4) 32cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::little, 4, false>>( 33cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Obj), EC)); 34d9d2f187759d0154574657c195068d367c338473Michael J. Spencer else 35d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif 36d9d2f187759d0154574657c195068d367c338473Michael J. Spencer if (MaxAlignment >= 2) 37cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::little, 2, false>>( 38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Obj), EC)); 394d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer else 40cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return object_error::parse_failed; 41f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB) 42d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST 434d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer if (MaxAlignment >= 4) 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::big, 4, false>>(std::move(Obj), 45cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EC)); 46d9d2f187759d0154574657c195068d367c338473Michael J. Spencer else 47d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif 48d9d2f187759d0154574657c195068d367c338473Michael J. Spencer if (MaxAlignment >= 2) 49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::big, 2, false>>(std::move(Obj), 50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EC)); 514d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer else 52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return object_error::parse_failed; 53f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB) 54d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST 554d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer if (MaxAlignment >= 8) 56cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::big, 8, true>>(std::move(Obj), 57cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EC)); 58d9d2f187759d0154574657c195068d367c338473Michael J. Spencer else 59d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif 60d9d2f187759d0154574657c195068d367c338473Michael J. Spencer if (MaxAlignment >= 2) 61cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::big, 2, true>>(std::move(Obj), 62cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EC)); 634d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer else 64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return object_error::parse_failed; 65f4eff4baeb44f9dee988e9293d029dcaa359420dEli Bendersky else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) { 66d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#if !LLVM_IS_UNALIGNED_ACCESS_FAST 674d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer if (MaxAlignment >= 8) 68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::little, 8, true>>( 69cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Obj), EC)); 70d9d2f187759d0154574657c195068d367c338473Michael J. Spencer else 71d9d2f187759d0154574657c195068d367c338473Michael J. Spencer#endif 72d9d2f187759d0154574657c195068d367c338473Michael J. Spencer if (MaxAlignment >= 2) 73cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines R.reset(new ELFObjectFile<ELFType<support::little, 2, true>>( 74cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::move(Obj), EC)); 754d9c5397b4a3be747bdb73f1d24c3fdbaaf438feMichael J. Spencer else 76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return object_error::parse_failed; 77bfbbe328371772a1b8408066f976a374b379e684Nick Lewycky } 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines llvm_unreachable("Buffer is not an ELF object file!"); 804344b1ef9b3721a5ebc2e024f753772a1e4ddd92Michael J. Spencer 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (EC) 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return R.release(); 840fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer} 850fcab076f0358890e2f1b213f4303c780e05d99dBenjamin Kramer 86b84551a14f1c96942eb82408652e633543b0961eMichael J. Spencer} // end namespace llvm 87