Line data Source code
1 : //===- Object.cpp - C bindings to the object file library--------*- 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 : //
10 : // This file defines the C bindings to the file-format-independent object
11 : // library.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #include "llvm-c/Object.h"
16 : #include "llvm/ADT/SmallVector.h"
17 : #include "llvm/Object/ObjectFile.h"
18 :
19 : using namespace llvm;
20 : using namespace object;
21 :
22 : inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
23 : return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
24 : }
25 :
26 : inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
27 : return reinterpret_cast<LLVMObjectFileRef>(
28 : const_cast<OwningBinary<ObjectFile> *>(OF));
29 : }
30 :
31 : inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
32 : return reinterpret_cast<section_iterator*>(SI);
33 : }
34 :
35 : inline LLVMSectionIteratorRef
36 : wrap(const section_iterator *SI) {
37 : return reinterpret_cast<LLVMSectionIteratorRef>
38 : (const_cast<section_iterator*>(SI));
39 : }
40 :
41 : inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
42 : return reinterpret_cast<symbol_iterator*>(SI);
43 : }
44 :
45 : inline LLVMSymbolIteratorRef
46 : wrap(const symbol_iterator *SI) {
47 : return reinterpret_cast<LLVMSymbolIteratorRef>
48 : (const_cast<symbol_iterator*>(SI));
49 : }
50 :
51 : inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
52 : return reinterpret_cast<relocation_iterator*>(SI);
53 : }
54 :
55 : inline LLVMRelocationIteratorRef
56 : wrap(const relocation_iterator *SI) {
57 : return reinterpret_cast<LLVMRelocationIteratorRef>
58 : (const_cast<relocation_iterator*>(SI));
59 : }
60 :
61 : // ObjectFile creation
62 1 : LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
63 : std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
64 : Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
65 3 : ObjectFile::createObjectFile(Buf->getMemBufferRef()));
66 : std::unique_ptr<ObjectFile> Obj;
67 1 : if (!ObjOrErr) {
68 : // TODO: Actually report errors helpfully.
69 1 : consumeError(ObjOrErr.takeError());
70 1 : return nullptr;
71 : }
72 :
73 0 : auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
74 0 : return wrap(Ret);
75 : }
76 :
77 0 : void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
78 0 : delete unwrap(ObjectFile);
79 0 : }
80 :
81 : // ObjectFile Section iterators
82 0 : LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
83 : OwningBinary<ObjectFile> *OB = unwrap(OF);
84 0 : section_iterator SI = OB->getBinary()->section_begin();
85 0 : return wrap(new section_iterator(SI));
86 : }
87 :
88 0 : void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
89 0 : delete unwrap(SI);
90 0 : }
91 :
92 0 : LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
93 : LLVMSectionIteratorRef SI) {
94 : OwningBinary<ObjectFile> *OB = unwrap(OF);
95 0 : return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
96 : }
97 :
98 0 : void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
99 : ++(*unwrap(SI));
100 0 : }
101 :
102 0 : void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
103 : LLVMSymbolIteratorRef Sym) {
104 : Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
105 0 : if (!SecOrErr) {
106 : std::string Buf;
107 : raw_string_ostream OS(Buf);
108 0 : logAllUnhandledErrors(SecOrErr.takeError(), OS, "");
109 : OS.flush();
110 0 : report_fatal_error(Buf);
111 : }
112 0 : *unwrap(Sect) = *SecOrErr;
113 0 : }
114 :
115 : // ObjectFile Symbol iterators
116 0 : LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
117 : OwningBinary<ObjectFile> *OB = unwrap(OF);
118 0 : symbol_iterator SI = OB->getBinary()->symbol_begin();
119 0 : return wrap(new symbol_iterator(SI));
120 : }
121 :
122 0 : void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
123 0 : delete unwrap(SI);
124 0 : }
125 :
126 0 : LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
127 : LLVMSymbolIteratorRef SI) {
128 : OwningBinary<ObjectFile> *OB = unwrap(OF);
129 0 : return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
130 : }
131 :
132 0 : void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
133 : ++(*unwrap(SI));
134 0 : }
135 :
136 : // SectionRef accessors
137 0 : const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
138 0 : StringRef ret;
139 0 : if (std::error_code ec = (*unwrap(SI))->getName(ret))
140 0 : report_fatal_error(ec.message());
141 0 : return ret.data();
142 : }
143 :
144 0 : uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
145 0 : return (*unwrap(SI))->getSize();
146 : }
147 :
148 0 : const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
149 0 : StringRef ret;
150 0 : if (std::error_code ec = (*unwrap(SI))->getContents(ret))
151 0 : report_fatal_error(ec.message());
152 0 : return ret.data();
153 : }
154 :
155 0 : uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
156 0 : return (*unwrap(SI))->getAddress();
157 : }
158 :
159 0 : LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
160 : LLVMSymbolIteratorRef Sym) {
161 0 : return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
162 : }
163 :
164 : // Section Relocation iterators
165 0 : LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
166 0 : relocation_iterator SI = (*unwrap(Section))->relocation_begin();
167 0 : return wrap(new relocation_iterator(SI));
168 : }
169 :
170 0 : void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
171 0 : delete unwrap(SI);
172 0 : }
173 :
174 0 : LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
175 : LLVMRelocationIteratorRef SI) {
176 0 : return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
177 : }
178 :
179 0 : void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
180 : ++(*unwrap(SI));
181 0 : }
182 :
183 :
184 : // SymbolRef accessors
185 0 : const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
186 : Expected<StringRef> Ret = (*unwrap(SI))->getName();
187 0 : if (!Ret) {
188 : std::string Buf;
189 : raw_string_ostream OS(Buf);
190 0 : logAllUnhandledErrors(Ret.takeError(), OS, "");
191 : OS.flush();
192 0 : report_fatal_error(Buf);
193 : }
194 0 : return Ret->data();
195 : }
196 :
197 0 : uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
198 : Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
199 0 : if (!Ret) {
200 : std::string Buf;
201 : raw_string_ostream OS(Buf);
202 0 : logAllUnhandledErrors(Ret.takeError(), OS, "");
203 : OS.flush();
204 0 : report_fatal_error(Buf);
205 : }
206 0 : return *Ret;
207 : }
208 :
209 0 : uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
210 0 : return (*unwrap(SI))->getCommonSize();
211 : }
212 :
213 : // RelocationRef accessors
214 0 : uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
215 0 : return (*unwrap(RI))->getOffset();
216 : }
217 :
218 0 : LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
219 0 : symbol_iterator ret = (*unwrap(RI))->getSymbol();
220 0 : return wrap(new symbol_iterator(ret));
221 : }
222 :
223 0 : uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
224 0 : return (*unwrap(RI))->getType();
225 : }
226 :
227 : // NOTE: Caller takes ownership of returned string.
228 0 : const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
229 : SmallVector<char, 0> ret;
230 0 : (*unwrap(RI))->getTypeName(ret);
231 0 : char *str = static_cast<char*>(safe_malloc(ret.size()));
232 : std::copy(ret.begin(), ret.end(), str);
233 0 : return str;
234 : }
235 :
236 : // NOTE: Caller takes ownership of returned string.
237 0 : const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
238 0 : return strdup("");
239 : }
240 :
|