121
|
1 //===- ObjectFile.cpp - File format independent object file ---------------===//
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
147
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 // This file defines a file format independent ObjectFile class.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12
|
121
|
13 #include "llvm/Object/ObjectFile.h"
|
|
14 #include "llvm/ADT/StringRef.h"
|
|
15 #include "llvm/BinaryFormat/Magic.h"
|
|
16 #include "llvm/Object/Binary.h"
|
77
|
17 #include "llvm/Object/COFF.h"
|
121
|
18 #include "llvm/Object/Error.h"
|
77
|
19 #include "llvm/Object/MachO.h"
|
121
|
20 #include "llvm/Object/Wasm.h"
|
|
21 #include "llvm/Support/Error.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "llvm/Support/ErrorHandling.h"
|
121
|
23 #include "llvm/Support/ErrorOr.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 #include "llvm/Support/FileSystem.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 #include "llvm/Support/MemoryBuffer.h"
|
77
|
26 #include "llvm/Support/raw_ostream.h"
|
121
|
27 #include <algorithm>
|
|
28 #include <cstdint>
|
|
29 #include <memory>
|
77
|
30 #include <system_error>
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33 using namespace object;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34
|
121
|
35 void ObjectFile::anchor() {}
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36
|
77
|
37 ObjectFile::ObjectFile(unsigned int Type, MemoryBufferRef Source)
|
|
38 : SymbolicFile(Type, Source) {}
|
|
39
|
95
|
40 bool SectionRef::containsSymbol(SymbolRef S) const {
|
120
|
41 Expected<section_iterator> SymSec = S.getSection();
|
|
42 if (!SymSec) {
|
|
43 // TODO: Actually report errors helpfully.
|
|
44 consumeError(SymSec.takeError());
|
95
|
45 return false;
|
120
|
46 }
|
95
|
47 return *this == **SymSec;
|
|
48 }
|
|
49
|
|
50 uint64_t ObjectFile::getSymbolValue(DataRefImpl Ref) const {
|
|
51 uint32_t Flags = getSymbolFlags(Ref);
|
|
52 if (Flags & SymbolRef::SF_Undefined)
|
|
53 return 0;
|
|
54 if (Flags & SymbolRef::SF_Common)
|
|
55 return getCommonSymbolSize(Ref);
|
|
56 return getSymbolValueImpl(Ref);
|
|
57 }
|
|
58
|
147
|
59 Error ObjectFile::printSymbolName(raw_ostream &OS, DataRefImpl Symb) const {
|
120
|
60 Expected<StringRef> Name = getSymbolName(Symb);
|
|
61 if (!Name)
|
147
|
62 return Name.takeError();
|
95
|
63 OS << *Name;
|
147
|
64 return Error::success();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
65 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
66
|
95
|
67 uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
68
|
120
|
69 bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
|
147
|
70 if (Expected<StringRef> NameOrErr = getSectionName(Sec))
|
|
71 return *NameOrErr == ".llvmbc";
|
120
|
72 return false;
|
|
73 }
|
|
74
|
121
|
75 bool ObjectFile::isSectionStripped(DataRefImpl Sec) const { return false; }
|
|
76
|
147
|
77 bool ObjectFile::isBerkeleyText(DataRefImpl Sec) const {
|
|
78 return isSectionText(Sec);
|
|
79 }
|
|
80
|
|
81 bool ObjectFile::isBerkeleyData(DataRefImpl Sec) const {
|
|
82 return isSectionData(Sec);
|
|
83 }
|
|
84
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
85 section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86 return section_iterator(SectionRef(Sec, this));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
87 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
88
|
121
|
89 Triple ObjectFile::makeTriple() const {
|
|
90 Triple TheTriple;
|
|
91 auto Arch = getArch();
|
|
92 TheTriple.setArch(Triple::ArchType(Arch));
|
|
93
|
|
94 // For ARM targets, try to use the build attributes to build determine
|
|
95 // the build target. Target features are also added, but later during
|
|
96 // disassembly.
|
|
97 if (Arch == Triple::arm || Arch == Triple::armeb)
|
|
98 setARMSubArch(TheTriple);
|
|
99
|
|
100 // TheTriple defaults to ELF, and COFF doesn't have an environment:
|
|
101 // the best we can do here is indicate that it is mach-o.
|
|
102 if (isMachO())
|
|
103 TheTriple.setObjectFormat(Triple::MachO);
|
|
104
|
|
105 if (isCOFF()) {
|
|
106 const auto COFFObj = dyn_cast<COFFObjectFile>(this);
|
|
107 if (COFFObj->getArch() == Triple::thumb)
|
|
108 TheTriple.setTriple("thumbv7-windows");
|
|
109 }
|
|
110
|
|
111 return TheTriple;
|
|
112 }
|
|
113
|
120
|
114 Expected<std::unique_ptr<ObjectFile>>
|
121
|
115 ObjectFile::createObjectFile(MemoryBufferRef Object, file_magic Type) {
|
77
|
116 StringRef Data = Object.getBuffer();
|
121
|
117 if (Type == file_magic::unknown)
|
|
118 Type = identify_magic(Data);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
119
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 switch (Type) {
|
121
|
121 case file_magic::unknown:
|
|
122 case file_magic::bitcode:
|
|
123 case file_magic::coff_cl_gl_object:
|
|
124 case file_magic::archive:
|
|
125 case file_magic::macho_universal_binary:
|
|
126 case file_magic::windows_resource:
|
147
|
127 case file_magic::pdb:
|
|
128 case file_magic::minidump:
|
120
|
129 return errorCodeToError(object_error::invalid_file_type);
|
121
|
130 case file_magic::elf:
|
|
131 case file_magic::elf_relocatable:
|
|
132 case file_magic::elf_executable:
|
|
133 case file_magic::elf_shared_object:
|
|
134 case file_magic::elf_core:
|
|
135 return createELFObjectFile(Object);
|
|
136 case file_magic::macho_object:
|
|
137 case file_magic::macho_executable:
|
|
138 case file_magic::macho_fixed_virtual_memory_shared_lib:
|
|
139 case file_magic::macho_core:
|
|
140 case file_magic::macho_preload_executable:
|
|
141 case file_magic::macho_dynamically_linked_shared_lib:
|
|
142 case file_magic::macho_dynamic_linker:
|
|
143 case file_magic::macho_bundle:
|
|
144 case file_magic::macho_dynamically_linked_shared_lib_stub:
|
|
145 case file_magic::macho_dsym_companion:
|
|
146 case file_magic::macho_kext_bundle:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 return createMachOObjectFile(Object);
|
121
|
148 case file_magic::coff_object:
|
|
149 case file_magic::coff_import_library:
|
|
150 case file_magic::pecoff_executable:
|
|
151 return createCOFFObjectFile(Object);
|
147
|
152 case file_magic::xcoff_object_32:
|
|
153 return createXCOFFObjectFile(Object, Binary::ID_XCOFF32);
|
|
154 case file_magic::xcoff_object_64:
|
|
155 return createXCOFFObjectFile(Object, Binary::ID_XCOFF64);
|
121
|
156 case file_magic::wasm_object:
|
|
157 return createWasmObjectFile(Object);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 llvm_unreachable("Unexpected Object File Type");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161
|
120
|
162 Expected<OwningBinary<ObjectFile>>
|
77
|
163 ObjectFile::createObjectFile(StringRef ObjectPath) {
|
|
164 ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
|
|
165 MemoryBuffer::getFile(ObjectPath);
|
|
166 if (std::error_code EC = FileOrErr.getError())
|
120
|
167 return errorCodeToError(EC);
|
77
|
168 std::unique_ptr<MemoryBuffer> Buffer = std::move(FileOrErr.get());
|
|
169
|
120
|
170 Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
|
77
|
171 createObjectFile(Buffer->getMemBufferRef());
|
120
|
172 if (Error Err = ObjOrErr.takeError())
|
|
173 return std::move(Err);
|
77
|
174 std::unique_ptr<ObjectFile> Obj = std::move(ObjOrErr.get());
|
|
175
|
|
176 return OwningBinary<ObjectFile>(std::move(Obj), std::move(Buffer));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177 }
|