1 //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the C bindings to the file-format-independent object
12 //===----------------------------------------------------------------------===//
14 #include "llvm-c/Object.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/Object/ObjectFile.h"
19 using namespace object
;
21 inline OwningBinary
<ObjectFile
> *unwrap(LLVMObjectFileRef OF
) {
22 return reinterpret_cast<OwningBinary
<ObjectFile
> *>(OF
);
25 inline LLVMObjectFileRef
wrap(const OwningBinary
<ObjectFile
> *OF
) {
26 return reinterpret_cast<LLVMObjectFileRef
>(
27 const_cast<OwningBinary
<ObjectFile
> *>(OF
));
30 inline section_iterator
*unwrap(LLVMSectionIteratorRef SI
) {
31 return reinterpret_cast<section_iterator
*>(SI
);
34 inline LLVMSectionIteratorRef
35 wrap(const section_iterator
*SI
) {
36 return reinterpret_cast<LLVMSectionIteratorRef
>
37 (const_cast<section_iterator
*>(SI
));
40 inline symbol_iterator
*unwrap(LLVMSymbolIteratorRef SI
) {
41 return reinterpret_cast<symbol_iterator
*>(SI
);
44 inline LLVMSymbolIteratorRef
45 wrap(const symbol_iterator
*SI
) {
46 return reinterpret_cast<LLVMSymbolIteratorRef
>
47 (const_cast<symbol_iterator
*>(SI
));
50 inline relocation_iterator
*unwrap(LLVMRelocationIteratorRef SI
) {
51 return reinterpret_cast<relocation_iterator
*>(SI
);
54 inline LLVMRelocationIteratorRef
55 wrap(const relocation_iterator
*SI
) {
56 return reinterpret_cast<LLVMRelocationIteratorRef
>
57 (const_cast<relocation_iterator
*>(SI
));
60 // ObjectFile creation
61 LLVMObjectFileRef
LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf
) {
62 std::unique_ptr
<MemoryBuffer
> Buf(unwrap(MemBuf
));
63 Expected
<std::unique_ptr
<ObjectFile
>> ObjOrErr(
64 ObjectFile::createObjectFile(Buf
->getMemBufferRef()));
65 std::unique_ptr
<ObjectFile
> Obj
;
67 // TODO: Actually report errors helpfully.
68 consumeError(ObjOrErr
.takeError());
72 auto *Ret
= new OwningBinary
<ObjectFile
>(std::move(ObjOrErr
.get()), std::move(Buf
));
76 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile
) {
77 delete unwrap(ObjectFile
);
80 // ObjectFile Section iterators
81 LLVMSectionIteratorRef
LLVMGetSections(LLVMObjectFileRef OF
) {
82 OwningBinary
<ObjectFile
> *OB
= unwrap(OF
);
83 section_iterator SI
= OB
->getBinary()->section_begin();
84 return wrap(new section_iterator(SI
));
87 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI
) {
91 LLVMBool
LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF
,
92 LLVMSectionIteratorRef SI
) {
93 OwningBinary
<ObjectFile
> *OB
= unwrap(OF
);
94 return (*unwrap(SI
) == OB
->getBinary()->section_end()) ? 1 : 0;
97 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI
) {
101 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect
,
102 LLVMSymbolIteratorRef Sym
) {
103 Expected
<section_iterator
> SecOrErr
= (*unwrap(Sym
))->getSection();
106 raw_string_ostream
OS(Buf
);
107 logAllUnhandledErrors(SecOrErr
.takeError(), OS
);
109 report_fatal_error(Buf
);
111 *unwrap(Sect
) = *SecOrErr
;
114 // ObjectFile Symbol iterators
115 LLVMSymbolIteratorRef
LLVMGetSymbols(LLVMObjectFileRef OF
) {
116 OwningBinary
<ObjectFile
> *OB
= unwrap(OF
);
117 symbol_iterator SI
= OB
->getBinary()->symbol_begin();
118 return wrap(new symbol_iterator(SI
));
121 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI
) {
125 LLVMBool
LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF
,
126 LLVMSymbolIteratorRef SI
) {
127 OwningBinary
<ObjectFile
> *OB
= unwrap(OF
);
128 return (*unwrap(SI
) == OB
->getBinary()->symbol_end()) ? 1 : 0;
131 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI
) {
135 // SectionRef accessors
136 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI
) {
138 if (std::error_code ec
= (*unwrap(SI
))->getName(ret
))
139 report_fatal_error(ec
.message());
143 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI
) {
144 return (*unwrap(SI
))->getSize();
147 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI
) {
149 if (std::error_code ec
= (*unwrap(SI
))->getContents(ret
))
150 report_fatal_error(ec
.message());
154 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI
) {
155 return (*unwrap(SI
))->getAddress();
158 LLVMBool
LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI
,
159 LLVMSymbolIteratorRef Sym
) {
160 return (*unwrap(SI
))->containsSymbol(**unwrap(Sym
));
163 // Section Relocation iterators
164 LLVMRelocationIteratorRef
LLVMGetRelocations(LLVMSectionIteratorRef Section
) {
165 relocation_iterator SI
= (*unwrap(Section
))->relocation_begin();
166 return wrap(new relocation_iterator(SI
));
169 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI
) {
173 LLVMBool
LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section
,
174 LLVMRelocationIteratorRef SI
) {
175 return (*unwrap(SI
) == (*unwrap(Section
))->relocation_end()) ? 1 : 0;
178 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI
) {
183 // SymbolRef accessors
184 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI
) {
185 Expected
<StringRef
> Ret
= (*unwrap(SI
))->getName();
188 raw_string_ostream
OS(Buf
);
189 logAllUnhandledErrors(Ret
.takeError(), OS
);
191 report_fatal_error(Buf
);
196 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI
) {
197 Expected
<uint64_t> Ret
= (*unwrap(SI
))->getAddress();
200 raw_string_ostream
OS(Buf
);
201 logAllUnhandledErrors(Ret
.takeError(), OS
);
203 report_fatal_error(Buf
);
208 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI
) {
209 return (*unwrap(SI
))->getCommonSize();
212 // RelocationRef accessors
213 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI
) {
214 return (*unwrap(RI
))->getOffset();
217 LLVMSymbolIteratorRef
LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI
) {
218 symbol_iterator ret
= (*unwrap(RI
))->getSymbol();
219 return wrap(new symbol_iterator(ret
));
222 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI
) {
223 return (*unwrap(RI
))->getType();
226 // NOTE: Caller takes ownership of returned string.
227 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI
) {
228 SmallVector
<char, 0> ret
;
229 (*unwrap(RI
))->getTypeName(ret
);
230 char *str
= static_cast<char*>(safe_malloc(ret
.size()));
231 llvm::copy(ret
, str
);
235 // NOTE: Caller takes ownership of returned string.
236 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI
) {