LLVM  10.0.0svn
Object.cpp
Go to the documentation of this file.
1 //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the C bindings to the file-format-independent object
10 // library.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm-c/Object.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/IR/LLVMContext.h"
17 #include "llvm/Object/ObjectFile.h"
19 
20 using namespace llvm;
21 using namespace object;
22 
23 inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
24  return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
25 }
26 
27 inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
28  return reinterpret_cast<LLVMObjectFileRef>(
29  const_cast<OwningBinary<ObjectFile> *>(OF));
30 }
31 
33  return reinterpret_cast<section_iterator*>(SI);
34 }
35 
38  return reinterpret_cast<LLVMSectionIteratorRef>
39  (const_cast<section_iterator*>(SI));
40 }
41 
42 inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
43  return reinterpret_cast<symbol_iterator*>(SI);
44 }
45 
47 wrap(const symbol_iterator *SI) {
48  return reinterpret_cast<LLVMSymbolIteratorRef>
49  (const_cast<symbol_iterator*>(SI));
50 }
51 
53  return reinterpret_cast<relocation_iterator*>(SI);
54 }
55 
58  return reinterpret_cast<LLVMRelocationIteratorRef>
59  (const_cast<relocation_iterator*>(SI));
60 }
61 
62 /*--.. Operations on binary files ..........................................--*/
63 
66  char **ErrorMessage) {
67  auto maybeContext = Context ? unwrap(Context) : nullptr;
69  createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext));
70  if (!ObjOrErr) {
71  *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
72  return nullptr;
73  }
74 
75  return wrap(ObjOrErr.get().release());
76 }
77 
79  auto Buf = unwrap(BR)->getMemoryBufferRef();
81  Buf.getBuffer(), Buf.getBufferIdentifier(),
82  /*RequiresNullTerminator*/false).release());
83 }
84 
86  delete unwrap(BR);
87 }
88 
90  class BinaryTypeMapper final : public Binary {
91  public:
92  static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) {
93  switch (Kind) {
94  case ID_Archive:
95  return LLVMBinaryTypeArchive;
96  case ID_MachOUniversalBinary:
98  case ID_COFFImportFile:
100  case ID_IR:
101  return LLVMBinaryTypeIR;
102  case ID_WinRes:
103  return LLVMBinaryTypeWinRes;
104  case ID_COFF:
105  return LLVMBinaryTypeCOFF;
106  case ID_ELF32L:
107  return LLVMBinaryTypeELF32L;
108  case ID_ELF32B:
109  return LLVMBinaryTypeELF32B;
110  case ID_ELF64L:
111  return LLVMBinaryTypeELF64L;
112  case ID_ELF64B:
113  return LLVMBinaryTypeELF64B;
114  case ID_MachO32L:
115  return LLVMBinaryTypeMachO32L;
116  case ID_MachO32B:
117  return LLVMBinaryTypeMachO32B;
118  case ID_MachO64L:
119  return LLVMBinaryTypeMachO64L;
120  case ID_MachO64B:
121  return LLVMBinaryTypeMachO64B;
122  case ID_Wasm:
123  return LLVMBinaryTypeWasm;
124  case ID_StartObjects:
125  case ID_EndObjects:
126  llvm_unreachable("Marker types are not valid binary kinds!");
127  default:
128  llvm_unreachable("Unknown binary kind!");
129  }
130  }
131  };
132  return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType());
133 }
134 
136  const char *Arch,
137  size_t ArchLen,
138  char **ErrorMessage) {
139  auto universal = cast<MachOUniversalBinary>(unwrap(BR));
141  universal->getMachOObjectForArch({Arch, ArchLen}));
142  if (!ObjOrErr) {
143  *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
144  return nullptr;
145  }
146  return wrap(ObjOrErr.get().release());
147 }
148 
150  auto OF = cast<ObjectFile>(unwrap(BR));
151  auto sections = OF->sections();
152  if (sections.begin() == sections.end())
153  return nullptr;
154  return wrap(new section_iterator(sections.begin()));
155 }
156 
159  auto OF = cast<ObjectFile>(unwrap(BR));
160  return (*unwrap(SI) == OF->section_end()) ? 1 : 0;
161 }
162 
164  auto OF = cast<ObjectFile>(unwrap(BR));
165  auto symbols = OF->symbols();
166  if (symbols.begin() == symbols.end())
167  return nullptr;
168  return wrap(new symbol_iterator(symbols.begin()));
169 }
170 
173  auto OF = cast<ObjectFile>(unwrap(BR));
174  return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0;
175 }
176 
177 // ObjectFile creation
179  std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
181  ObjectFile::createObjectFile(Buf->getMemBufferRef()));
182  std::unique_ptr<ObjectFile> Obj;
183  if (!ObjOrErr) {
184  // TODO: Actually report errors helpfully.
185  consumeError(ObjOrErr.takeError());
186  return nullptr;
187  }
188 
189  auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
190  return wrap(Ret);
191 }
192 
194  delete unwrap(ObjectFile);
195 }
196 
197 // ObjectFile Section iterators
199  OwningBinary<ObjectFile> *OB = unwrap(OF);
200  section_iterator SI = OB->getBinary()->section_begin();
201  return wrap(new section_iterator(SI));
202 }
203 
205  delete unwrap(SI);
206 }
207 
210  OwningBinary<ObjectFile> *OB = unwrap(OF);
211  return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
212 }
213 
215  ++(*unwrap(SI));
216 }
217 
219  LLVMSymbolIteratorRef Sym) {
220  Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
221  if (!SecOrErr) {
222  std::string Buf;
223  raw_string_ostream OS(Buf);
224  logAllUnhandledErrors(SecOrErr.takeError(), OS);
225  OS.flush();
226  report_fatal_error(Buf);
227  }
228  *unwrap(Sect) = *SecOrErr;
229 }
230 
231 // ObjectFile Symbol iterators
233  OwningBinary<ObjectFile> *OB = unwrap(OF);
234  symbol_iterator SI = OB->getBinary()->symbol_begin();
235  return wrap(new symbol_iterator(SI));
236 }
237 
239  delete unwrap(SI);
240 }
241 
244  OwningBinary<ObjectFile> *OB = unwrap(OF);
245  return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
246 }
247 
249  ++(*unwrap(SI));
250 }
251 
252 // SectionRef accessors
254  auto NameOrErr = (*unwrap(SI))->getName();
255  if (!NameOrErr)
256  report_fatal_error(NameOrErr.takeError());
257  return NameOrErr->data();
258 }
259 
261  return (*unwrap(SI))->getSize();
262 }
263 
265  if (Expected<StringRef> E = (*unwrap(SI))->getContents())
266  return E->data();
267  else
268  report_fatal_error(E.takeError());
269 }
270 
272  return (*unwrap(SI))->getAddress();
273 }
274 
276  LLVMSymbolIteratorRef Sym) {
277  return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
278 }
279 
280 // Section Relocation iterators
282  relocation_iterator SI = (*unwrap(Section))->relocation_begin();
283  return wrap(new relocation_iterator(SI));
284 }
285 
287  delete unwrap(SI);
288 }
289 
292  return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
293 }
294 
296  ++(*unwrap(SI));
297 }
298 
299 
300 // SymbolRef accessors
303  if (!Ret) {
304  std::string Buf;
305  raw_string_ostream OS(Buf);
306  logAllUnhandledErrors(Ret.takeError(), OS);
307  OS.flush();
308  report_fatal_error(Buf);
309  }
310  return Ret->data();
311 }
312 
314  Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
315  if (!Ret) {
316  std::string Buf;
317  raw_string_ostream OS(Buf);
318  logAllUnhandledErrors(Ret.takeError(), OS);
319  OS.flush();
320  report_fatal_error(Buf);
321  }
322  return *Ret;
323 }
324 
326  return (*unwrap(SI))->getCommonSize();
327 }
328 
329 // RelocationRef accessors
331  return (*unwrap(RI))->getOffset();
332 }
333 
335  symbol_iterator ret = (*unwrap(RI))->getSymbol();
336  return wrap(new symbol_iterator(ret));
337 }
338 
340  return (*unwrap(RI))->getType();
341 }
342 
343 // NOTE: Caller takes ownership of returned string.
346  (*unwrap(RI))->getTypeName(ret);
347  char *str = static_cast<char*>(safe_malloc(ret.size()));
348  llvm::copy(ret, str);
349  return str;
350 }
351 
352 // NOTE: Caller takes ownership of returned string.
354  return strdup("");
355 }
356 
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
Definition: ObjectFile.cpp:167
LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR)
Retrieve the specific type of a binary.
Definition: Object.cpp:89
LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR, const char *Arch, size_t ArchLen, char **ErrorMessage)
Definition: Object.cpp:135
LLVMContext & Context
uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI)
Definition: Object.cpp:271
MachO 64-bit, big endian.
Definition: Object.h:55
ELF 64-bit, little endian.
Definition: Object.h:50
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Web Assembly.
Definition: Object.h:56
struct LLVMOpaqueMemoryBuffer * LLVMMemoryBufferRef
LLVM uses a polymorphic type hierarchy which C cannot represent, therefore parameters must be passed ...
Definition: Types.h:49
LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, LLVMSymbolIteratorRef Sym)
Definition: Object.cpp:275
LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR, LLVMSectionIteratorRef SI)
Returns whether the given section iterator is at the end.
Definition: Object.cpp:157
StringRef getTypeName()
We provide a function which tries to compute the (demangled) name of a type statically.
Definition: TypeName.h:27
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
COFF Import file.
Definition: Object.h:44
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf)
Deprecated: Use LLVMCreateBinary instead.
Definition: Object.cpp:178
ELF 32-bit, big endian.
Definition: Object.h:49
MachO 32-bit, little endian.
Definition: Object.h:52
Error takeError()
Take ownership of the stored error.
Definition: Error.h:552
const char * LLVMGetSectionContents(LLVMSectionIteratorRef SI)
Definition: Object.cpp:264
Expected< std::unique_ptr< Binary > > createBinary(MemoryBufferRef Source, LLVMContext *Context=nullptr)
Create a Binary from Source, autodetecting the file type.
Definition: Binary.cpp:46
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:966
Attribute unwrap(LLVMAttributeRef Attr)
Definition: Attributes.h:204
LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, LLVMRelocationIteratorRef SI)
Definition: Object.cpp:290
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
Definition: yaml2obj.h:21
void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI)
Definition: Object.cpp:238
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Definition: ELF.h:310
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, LLVMSymbolIteratorRef Sym)
Definition: Object.cpp:218
LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, LLVMContextRef Context, char **ErrorMessage)
Create a binary file from the given memory buffer.
Definition: Object.cpp:64
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:48
struct LLVMOpaqueSectionIterator * LLVMSectionIteratorRef
Definition: Object.h:37
struct LLVMOpaqueContext * LLVMContextRef
The top-level container for all LLVM global data.
Definition: Types.h:54
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI)
Definition: Object.cpp:204
struct LLVMOpaqueBinary * LLVMBinaryRef
Definition: Types.h:169
void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI)
Definition: Object.cpp:295
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI)
Definition: Object.cpp:334
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:657
void LLVMDisposeBinary(LLVMBinaryRef BR)
Dispose of a binary file.
Definition: Object.cpp:85
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI)
Definition: Object.cpp:260
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
struct LLVMOpaqueSymbolIterator * LLVMSymbolIteratorRef
Definition: Object.h:38
LLVMBinaryType
Definition: Object.h:41
LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR, LLVMSymbolIteratorRef SI)
Returns whether the given symbol iterator is at the end.
Definition: Object.cpp:171
struct LLVMOpaqueObjectFile * LLVMObjectFileRef
Deprecated: Use LLVMBinaryRef instead.
Definition: Object.h:204
COFF Object file.
Definition: Object.h:47
Windows resource (.res) file.
Definition: Object.h:46
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, LLVMSectionIteratorRef SI)
Deprecated: Use LLVMObjectFileIsSectionIteratorAtEnd instead.
Definition: Object.cpp:208
int LLVMBool
Definition: Types.h:29
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:981
size_t size() const
Definition: SmallVector.h:52
static wasm::ValType getType(const TargetRegisterClass *RC)
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:61
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF)
Deprecated: Use LLVMObjectFileCopySymbolIterator instead.
Definition: Object.cpp:232
ELF 64-bit, big endian.
Definition: Object.h:51
ELF 32-bit, little endian.
Definition: Object.h:48
LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section)
Definition: Object.cpp:281
const char * LLVMGetSectionName(LLVMSectionIteratorRef SI)
Definition: Object.cpp:253
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
Definition: MemAlloc.h:25
SmallVectorImpl< T >::const_pointer c_str(SmallVectorImpl< T > &str)
LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR)
Retrieve a copy of the symbol iterator for this object file.
Definition: Object.cpp:163
const char * LLVMGetSymbolName(LLVMSymbolIteratorRef SI)
Definition: Object.cpp:301
MachO 64-bit, little endian.
Definition: Object.h:54
reference get()
Returns a reference to the stored T value.
Definition: Error.h:532
void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI)
Definition: Object.cpp:286
LLVM IR.
Definition: Object.h:45
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF)
Deprecated: Use LLVMObjectFileCopySectionIterator instead.
Definition: Object.cpp:198
Mach-O Universal Binary file.
Definition: Object.h:43
LLVMAttributeRef wrap(Attribute Attr)
Definition: Attributes.h:199
void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI)
Definition: Object.cpp:248
uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI)
Definition: Object.cpp:313
const char * LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI)
Definition: Object.cpp:344
struct LLVMOpaqueRelocationIterator * LLVMRelocationIteratorRef
Definition: Object.h:39
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI)
Definition: Object.cpp:330
LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR)
Retrieves a copy of the memory buffer associated with this object file.
Definition: Object.cpp:78
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI)
Definition: Object.cpp:339
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile)
Deprecated: Use LLVMDisposeBinary instead.
Definition: Object.cpp:193
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
MachO 32-bit, big endian.
Definition: Object.h:53
LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, LLVMSymbolIteratorRef SI)
Deprecated: Use LLVMObjectFileIsSymbolIteratorAtEnd instead.
Definition: Object.cpp:242
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:77
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI)
Definition: Object.cpp:325
const char * LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI)
Definition: Object.cpp:353
Archive file.
Definition: Object.h:42
LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR)
Retrieve a copy of the section iterator for this object file.
Definition: Object.cpp:149
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1217
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI)
Definition: Object.cpp:214