blob: c7df30a590351683055c28959b89ea32942f66ae [file] [log] [blame]
Michael J. Spencerb60a18d2011-01-20 06:38:47 +00001//===- ELFObjectFile.cpp - ELF object file implementation -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000010// Part of the ELFObjectFile class implementation.
Michael J. Spencerb60a18d2011-01-20 06:38:47 +000011//
12//===----------------------------------------------------------------------===//
13
Michael J. Spencer126973b2013-08-08 22:27:13 +000014#include "llvm/Object/ELFObjectFile.h"
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000015#include "llvm/Support/MathExtras.h"
Eli Benderskyc3c80f02012-01-22 09:01:03 +000016
Michael J. Spencerb60a18d2011-01-20 06:38:47 +000017namespace llvm {
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000018using namespace object;
Eli Benderskyc3c80f02012-01-22 09:01:03 +000019
Rafael Espindola48af1c22014-08-19 18:44:46 +000020ELFObjectFileBase::ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
21 : ObjectFile(Type, Source) {}
Rafael Espindolaab737742014-08-17 17:52:10 +000022
Rafael Espindola437b0d52014-07-31 03:12:45 +000023ErrorOr<std::unique_ptr<ObjectFile>>
Rafael Espindola48af1c22014-08-19 18:44:46 +000024ObjectFile::createELFObjectFile(MemoryBufferRef Obj) {
Rafael Espindolad5a8efe2014-07-05 11:38:52 +000025 std::pair<unsigned char, unsigned char> Ident =
Rafael Espindola48af1c22014-08-19 18:44:46 +000026 getElfArchType(Obj.getBuffer());
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000027 std::size_t MaxAlignment =
Rafael Espindola48af1c22014-08-19 18:44:46 +000028 1ULL << countTrailingZeros(uintptr_t(Obj.getBufferStart()));
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000029
Rafael Espindolaac729b42015-06-02 12:05:27 +000030 if (MaxAlignment < 2)
31 return object_error::parse_failed;
32
Rafael Espindoladb4ed0b2014-06-13 02:24:39 +000033 std::error_code EC;
Ahmed Charles56440fd2014-03-06 05:51:42 +000034 std::unique_ptr<ObjectFile> R;
Rafael Espindolaac729b42015-06-02 12:05:27 +000035 if (Ident.first == ELF::ELFCLASS32) {
36 if (Ident.second == ELF::ELFDATA2LSB)
37 R.reset(new ELFObjectFile<ELFType<support::little, false>>(Obj, EC));
38 else if (Ident.second == ELF::ELFDATA2MSB)
39 R.reset(new ELFObjectFile<ELFType<support::big, false>>(Obj, EC));
Michael J. Spencer39678d82013-02-03 10:48:31 +000040 else
Alexey Samsonov18ad2e52015-06-04 22:58:25 +000041 return object_error::parse_failed;
Alexey Samsonov49179dd2015-06-04 23:14:43 +000042 } else if (Ident.first == ELF::ELFCLASS64) {
Rafael Espindolaac729b42015-06-02 12:05:27 +000043 if (Ident.second == ELF::ELFDATA2LSB)
44 R.reset(new ELFObjectFile<ELFType<support::little, true>>(Obj, EC));
45 else if (Ident.second == ELF::ELFDATA2MSB)
46 R.reset(new ELFObjectFile<ELFType<support::big, true>>(Obj, EC));
Michael J. Spencerbae14ce2013-01-04 20:36:28 +000047 else
Alexey Samsonov18ad2e52015-06-04 22:58:25 +000048 return object_error::parse_failed;
Alexey Samsonov49179dd2015-06-04 23:14:43 +000049 } else {
50 return object_error::parse_failed;
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000051 }
52
Rafael Espindola692410e2014-01-21 23:06:54 +000053 if (EC)
54 return EC;
Rafael Espindola437b0d52014-07-31 03:12:45 +000055 return std::move(R);
Eli Benderskyc7d23dd2012-02-12 06:12:10 +000056}
Michael J. Spencerb60a18d2011-01-20 06:38:47 +000057
Michael J. Spencerb60a18d2011-01-20 06:38:47 +000058} // end namespace llvm