Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Object/Object.cpp
35232 views
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"
18
#include "llvm/Object/MachOUniversal.h"
19
#include "llvm/Support/MemAlloc.h"
20
21
using namespace llvm;
22
using namespace object;
23
24
inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
25
return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
26
}
27
28
inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
29
return reinterpret_cast<LLVMObjectFileRef>(
30
const_cast<OwningBinary<ObjectFile> *>(OF));
31
}
32
33
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
34
return reinterpret_cast<section_iterator*>(SI);
35
}
36
37
inline LLVMSectionIteratorRef
38
wrap(const section_iterator *SI) {
39
return reinterpret_cast<LLVMSectionIteratorRef>
40
(const_cast<section_iterator*>(SI));
41
}
42
43
inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
44
return reinterpret_cast<symbol_iterator*>(SI);
45
}
46
47
inline LLVMSymbolIteratorRef
48
wrap(const symbol_iterator *SI) {
49
return reinterpret_cast<LLVMSymbolIteratorRef>
50
(const_cast<symbol_iterator*>(SI));
51
}
52
53
inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
54
return reinterpret_cast<relocation_iterator*>(SI);
55
}
56
57
inline LLVMRelocationIteratorRef
58
wrap(const relocation_iterator *SI) {
59
return reinterpret_cast<LLVMRelocationIteratorRef>
60
(const_cast<relocation_iterator*>(SI));
61
}
62
63
/*--.. Operations on binary files ..........................................--*/
64
65
LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf,
66
LLVMContextRef Context,
67
char **ErrorMessage) {
68
auto maybeContext = Context ? unwrap(Context) : nullptr;
69
Expected<std::unique_ptr<Binary>> ObjOrErr(
70
createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext));
71
if (!ObjOrErr) {
72
*ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
73
return nullptr;
74
}
75
76
return wrap(ObjOrErr.get().release());
77
}
78
79
LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) {
80
auto Buf = unwrap(BR)->getMemoryBufferRef();
81
return wrap(llvm::MemoryBuffer::getMemBuffer(
82
Buf.getBuffer(), Buf.getBufferIdentifier(),
83
/*RequiresNullTerminator*/false).release());
84
}
85
86
void LLVMDisposeBinary(LLVMBinaryRef BR) {
87
delete unwrap(BR);
88
}
89
90
LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {
91
class BinaryTypeMapper final : public Binary {
92
public:
93
static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) {
94
switch (Kind) {
95
case ID_Archive:
96
return LLVMBinaryTypeArchive;
97
case ID_MachOUniversalBinary:
98
return LLVMBinaryTypeMachOUniversalBinary;
99
case ID_COFFImportFile:
100
return LLVMBinaryTypeCOFFImportFile;
101
case ID_IR:
102
return LLVMBinaryTypeIR;
103
case ID_WinRes:
104
return LLVMBinaryTypeWinRes;
105
case ID_COFF:
106
return LLVMBinaryTypeCOFF;
107
case ID_ELF32L:
108
return LLVMBinaryTypeELF32L;
109
case ID_ELF32B:
110
return LLVMBinaryTypeELF32B;
111
case ID_ELF64L:
112
return LLVMBinaryTypeELF64L;
113
case ID_ELF64B:
114
return LLVMBinaryTypeELF64B;
115
case ID_MachO32L:
116
return LLVMBinaryTypeMachO32L;
117
case ID_MachO32B:
118
return LLVMBinaryTypeMachO32B;
119
case ID_MachO64L:
120
return LLVMBinaryTypeMachO64L;
121
case ID_MachO64B:
122
return LLVMBinaryTypeMachO64B;
123
case ID_Offload:
124
return LLVMBinaryTypeOffload;
125
case ID_Wasm:
126
return LLVMBinaryTypeWasm;
127
case ID_StartObjects:
128
case ID_EndObjects:
129
llvm_unreachable("Marker types are not valid binary kinds!");
130
default:
131
llvm_unreachable("Unknown binary kind!");
132
}
133
}
134
};
135
return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType());
136
}
137
138
LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR,
139
const char *Arch,
140
size_t ArchLen,
141
char **ErrorMessage) {
142
auto universal = cast<MachOUniversalBinary>(unwrap(BR));
143
Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
144
universal->getMachOObjectForArch({Arch, ArchLen}));
145
if (!ObjOrErr) {
146
*ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
147
return nullptr;
148
}
149
return wrap(ObjOrErr.get().release());
150
}
151
152
LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) {
153
auto OF = cast<ObjectFile>(unwrap(BR));
154
auto sections = OF->sections();
155
if (sections.begin() == sections.end())
156
return nullptr;
157
return wrap(new section_iterator(sections.begin()));
158
}
159
160
LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR,
161
LLVMSectionIteratorRef SI) {
162
auto OF = cast<ObjectFile>(unwrap(BR));
163
return (*unwrap(SI) == OF->section_end()) ? 1 : 0;
164
}
165
166
LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) {
167
auto OF = cast<ObjectFile>(unwrap(BR));
168
auto symbols = OF->symbols();
169
if (symbols.begin() == symbols.end())
170
return nullptr;
171
return wrap(new symbol_iterator(symbols.begin()));
172
}
173
174
LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR,
175
LLVMSymbolIteratorRef SI) {
176
auto OF = cast<ObjectFile>(unwrap(BR));
177
return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0;
178
}
179
180
// ObjectFile creation
181
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
182
std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
183
Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
184
ObjectFile::createObjectFile(Buf->getMemBufferRef()));
185
std::unique_ptr<ObjectFile> Obj;
186
if (!ObjOrErr) {
187
// TODO: Actually report errors helpfully.
188
consumeError(ObjOrErr.takeError());
189
return nullptr;
190
}
191
192
auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
193
return wrap(Ret);
194
}
195
196
void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
197
delete unwrap(ObjectFile);
198
}
199
200
// ObjectFile Section iterators
201
LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
202
OwningBinary<ObjectFile> *OB = unwrap(OF);
203
section_iterator SI = OB->getBinary()->section_begin();
204
return wrap(new section_iterator(SI));
205
}
206
207
void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
208
delete unwrap(SI);
209
}
210
211
LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
212
LLVMSectionIteratorRef SI) {
213
OwningBinary<ObjectFile> *OB = unwrap(OF);
214
return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
215
}
216
217
void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
218
++(*unwrap(SI));
219
}
220
221
void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
222
LLVMSymbolIteratorRef Sym) {
223
Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
224
if (!SecOrErr) {
225
std::string Buf;
226
raw_string_ostream OS(Buf);
227
logAllUnhandledErrors(SecOrErr.takeError(), OS);
228
report_fatal_error(Twine(OS.str()));
229
}
230
*unwrap(Sect) = *SecOrErr;
231
}
232
233
// ObjectFile Symbol iterators
234
LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
235
OwningBinary<ObjectFile> *OB = unwrap(OF);
236
symbol_iterator SI = OB->getBinary()->symbol_begin();
237
return wrap(new symbol_iterator(SI));
238
}
239
240
void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
241
delete unwrap(SI);
242
}
243
244
LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
245
LLVMSymbolIteratorRef SI) {
246
OwningBinary<ObjectFile> *OB = unwrap(OF);
247
return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
248
}
249
250
void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
251
++(*unwrap(SI));
252
}
253
254
// SectionRef accessors
255
const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
256
auto NameOrErr = (*unwrap(SI))->getName();
257
if (!NameOrErr)
258
report_fatal_error(NameOrErr.takeError());
259
return NameOrErr->data();
260
}
261
262
uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
263
return (*unwrap(SI))->getSize();
264
}
265
266
const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
267
if (Expected<StringRef> E = (*unwrap(SI))->getContents())
268
return E->data();
269
else
270
report_fatal_error(E.takeError());
271
}
272
273
uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
274
return (*unwrap(SI))->getAddress();
275
}
276
277
LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
278
LLVMSymbolIteratorRef Sym) {
279
return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
280
}
281
282
// Section Relocation iterators
283
LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
284
relocation_iterator SI = (*unwrap(Section))->relocation_begin();
285
return wrap(new relocation_iterator(SI));
286
}
287
288
void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
289
delete unwrap(SI);
290
}
291
292
LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
293
LLVMRelocationIteratorRef SI) {
294
return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
295
}
296
297
void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
298
++(*unwrap(SI));
299
}
300
301
302
// SymbolRef accessors
303
const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
304
Expected<StringRef> Ret = (*unwrap(SI))->getName();
305
if (!Ret) {
306
std::string Buf;
307
raw_string_ostream OS(Buf);
308
logAllUnhandledErrors(Ret.takeError(), OS);
309
report_fatal_error(Twine(OS.str()));
310
}
311
return Ret->data();
312
}
313
314
uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
315
Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
316
if (!Ret) {
317
std::string Buf;
318
raw_string_ostream OS(Buf);
319
logAllUnhandledErrors(Ret.takeError(), OS);
320
report_fatal_error(Twine(OS.str()));
321
}
322
return *Ret;
323
}
324
325
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
326
return (*unwrap(SI))->getCommonSize();
327
}
328
329
// RelocationRef accessors
330
uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
331
return (*unwrap(RI))->getOffset();
332
}
333
334
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
335
symbol_iterator ret = (*unwrap(RI))->getSymbol();
336
return wrap(new symbol_iterator(ret));
337
}
338
339
uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
340
return (*unwrap(RI))->getType();
341
}
342
343
// NOTE: Caller takes ownership of returned string.
344
const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
345
SmallVector<char, 0> ret;
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.
353
const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
354
return strdup("");
355
}
356
357
358