1c56d2e8fSEric Christopher //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
2c56d2e8fSEric Christopher //
3c56d2e8fSEric Christopher //                     The LLVM Compiler Infrastructure
4c56d2e8fSEric Christopher //
5c56d2e8fSEric Christopher // This file is distributed under the University of Illinois Open Source
6c56d2e8fSEric Christopher // License. See LICENSE.TXT for details.
7c56d2e8fSEric Christopher //
8c56d2e8fSEric Christopher //===----------------------------------------------------------------------===//
9c56d2e8fSEric Christopher //
10c56d2e8fSEric Christopher // This file defines the C bindings to the file-format-independent object
11c56d2e8fSEric Christopher // library.
12c56d2e8fSEric Christopher //
13c56d2e8fSEric Christopher //===----------------------------------------------------------------------===//
14c56d2e8fSEric Christopher 
15dec20e43SFilip Pizlo #include "llvm/ADT/SmallVector.h"
16c56d2e8fSEric Christopher #include "llvm-c/Object.h"
178a8cd2baSChandler Carruth #include "llvm/Object/ObjectFile.h"
18c56d2e8fSEric Christopher 
19c56d2e8fSEric Christopher using namespace llvm;
20c56d2e8fSEric Christopher using namespace object;
21c56d2e8fSEric Christopher 
2204d4e931SEric Christopher inline ObjectFile *unwrap(LLVMObjectFileRef OF) {
2304d4e931SEric Christopher   return reinterpret_cast<ObjectFile*>(OF);
2404d4e931SEric Christopher }
2504d4e931SEric Christopher 
2604d4e931SEric Christopher inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
2704d4e931SEric Christopher   return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
2804d4e931SEric Christopher }
2904d4e931SEric Christopher 
3004d4e931SEric Christopher inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
3104d4e931SEric Christopher   return reinterpret_cast<section_iterator*>(SI);
3204d4e931SEric Christopher }
3304d4e931SEric Christopher 
3404d4e931SEric Christopher inline LLVMSectionIteratorRef
3504d4e931SEric Christopher wrap(const section_iterator *SI) {
3604d4e931SEric Christopher   return reinterpret_cast<LLVMSectionIteratorRef>
3704d4e931SEric Christopher     (const_cast<section_iterator*>(SI));
3804d4e931SEric Christopher }
3904d4e931SEric Christopher 
4004d4e931SEric Christopher inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
4104d4e931SEric Christopher   return reinterpret_cast<symbol_iterator*>(SI);
4204d4e931SEric Christopher }
4304d4e931SEric Christopher 
4404d4e931SEric Christopher inline LLVMSymbolIteratorRef
4504d4e931SEric Christopher wrap(const symbol_iterator *SI) {
4604d4e931SEric Christopher   return reinterpret_cast<LLVMSymbolIteratorRef>
4704d4e931SEric Christopher     (const_cast<symbol_iterator*>(SI));
4804d4e931SEric Christopher }
4904d4e931SEric Christopher 
5004d4e931SEric Christopher inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
5104d4e931SEric Christopher   return reinterpret_cast<relocation_iterator*>(SI);
5204d4e931SEric Christopher }
5304d4e931SEric Christopher 
5404d4e931SEric Christopher inline LLVMRelocationIteratorRef
5504d4e931SEric Christopher wrap(const relocation_iterator *SI) {
5604d4e931SEric Christopher   return reinterpret_cast<LLVMRelocationIteratorRef>
5704d4e931SEric Christopher     (const_cast<relocation_iterator*>(SI));
5804d4e931SEric Christopher }
5904d4e931SEric Christopher 
60f239db40SOwen Anderson // ObjectFile creation
61c56d2e8fSEric Christopher LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
62*51cc3602SRafael Espindola   ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf)));
63*51cc3602SRafael Espindola   ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : 0;
64*51cc3602SRafael Espindola   return wrap(Obj);
65c56d2e8fSEric Christopher }
66c56d2e8fSEric Christopher 
67c56d2e8fSEric Christopher void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
68c56d2e8fSEric Christopher   delete unwrap(ObjectFile);
69c56d2e8fSEric Christopher }
70c56d2e8fSEric Christopher 
71f239db40SOwen Anderson // ObjectFile Section iterators
72c56d2e8fSEric Christopher LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) {
73e5fd0047SMichael J. Spencer   section_iterator SI = unwrap(ObjectFile)->begin_sections();
74e5fd0047SMichael J. Spencer   return wrap(new section_iterator(SI));
75c56d2e8fSEric Christopher }
76c56d2e8fSEric Christopher 
77c56d2e8fSEric Christopher void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
78c56d2e8fSEric Christopher   delete unwrap(SI);
79c56d2e8fSEric Christopher }
80c56d2e8fSEric Christopher 
81c56d2e8fSEric Christopher LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
82c56d2e8fSEric Christopher                                 LLVMSectionIteratorRef SI) {
83c56d2e8fSEric Christopher   return (*unwrap(SI) == unwrap(ObjectFile)->end_sections()) ? 1 : 0;
84c56d2e8fSEric Christopher }
85c56d2e8fSEric Christopher 
86c56d2e8fSEric Christopher void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
871d6167fdSMichael J. Spencer   error_code ec;
881d6167fdSMichael J. Spencer   unwrap(SI)->increment(ec);
891d6167fdSMichael J. Spencer   if (ec) report_fatal_error("LLVMMoveToNextSection failed: " + ec.message());
90c56d2e8fSEric Christopher }
91c56d2e8fSEric Christopher 
9207bfdbb2SOwen Anderson void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
9307bfdbb2SOwen Anderson                                  LLVMSymbolIteratorRef Sym) {
9407bfdbb2SOwen Anderson   if (error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect)))
9507bfdbb2SOwen Anderson     report_fatal_error(ec.message());
9607bfdbb2SOwen Anderson }
9707bfdbb2SOwen Anderson 
98f239db40SOwen Anderson // ObjectFile Symbol iterators
99f239db40SOwen Anderson LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) {
100f239db40SOwen Anderson   symbol_iterator SI = unwrap(ObjectFile)->begin_symbols();
101f239db40SOwen Anderson   return wrap(new symbol_iterator(SI));
102f239db40SOwen Anderson }
103f239db40SOwen Anderson 
104f239db40SOwen Anderson void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
105f239db40SOwen Anderson   delete unwrap(SI);
106f239db40SOwen Anderson }
107f239db40SOwen Anderson 
108f239db40SOwen Anderson LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
109f239db40SOwen Anderson                                 LLVMSymbolIteratorRef SI) {
110f239db40SOwen Anderson   return (*unwrap(SI) == unwrap(ObjectFile)->end_symbols()) ? 1 : 0;
111f239db40SOwen Anderson }
112f239db40SOwen Anderson 
113f239db40SOwen Anderson void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
114f239db40SOwen Anderson   error_code ec;
115f239db40SOwen Anderson   unwrap(SI)->increment(ec);
116f239db40SOwen Anderson   if (ec) report_fatal_error("LLVMMoveToNextSymbol failed: " + ec.message());
117f239db40SOwen Anderson }
118f239db40SOwen Anderson 
119f239db40SOwen Anderson // SectionRef accessors
120c56d2e8fSEric Christopher const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
1211d6167fdSMichael J. Spencer   StringRef ret;
1221d6167fdSMichael J. Spencer   if (error_code ec = (*unwrap(SI))->getName(ret))
1231d6167fdSMichael J. Spencer    report_fatal_error(ec.message());
1241d6167fdSMichael J. Spencer   return ret.data();
125c56d2e8fSEric Christopher }
126c56d2e8fSEric Christopher 
127c56d2e8fSEric Christopher uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
1281d6167fdSMichael J. Spencer   uint64_t ret;
1291d6167fdSMichael J. Spencer   if (error_code ec = (*unwrap(SI))->getSize(ret))
1301d6167fdSMichael J. Spencer     report_fatal_error(ec.message());
1311d6167fdSMichael J. Spencer   return ret;
132c56d2e8fSEric Christopher }
133c56d2e8fSEric Christopher 
134c56d2e8fSEric Christopher const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
1351d6167fdSMichael J. Spencer   StringRef ret;
1361d6167fdSMichael J. Spencer   if (error_code ec = (*unwrap(SI))->getContents(ret))
1371d6167fdSMichael J. Spencer     report_fatal_error(ec.message());
1381d6167fdSMichael J. Spencer   return ret.data();
139c56d2e8fSEric Christopher }
140f239db40SOwen Anderson 
141f239db40SOwen Anderson uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
142f239db40SOwen Anderson   uint64_t ret;
143f239db40SOwen Anderson   if (error_code ec = (*unwrap(SI))->getAddress(ret))
144f239db40SOwen Anderson     report_fatal_error(ec.message());
145f239db40SOwen Anderson   return ret;
146f239db40SOwen Anderson }
147f239db40SOwen Anderson 
148500ebeb8SOwen Anderson LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
149f239db40SOwen Anderson                                  LLVMSymbolIteratorRef Sym) {
150f239db40SOwen Anderson   bool ret;
151f239db40SOwen Anderson   if (error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret))
152f239db40SOwen Anderson     report_fatal_error(ec.message());
153f239db40SOwen Anderson   return ret;
154f239db40SOwen Anderson }
155f239db40SOwen Anderson 
156e245af65SOwen Anderson // Section Relocation iterators
157e245af65SOwen Anderson LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
158e245af65SOwen Anderson   relocation_iterator SI = (*unwrap(Section))->begin_relocations();
159e245af65SOwen Anderson   return wrap(new relocation_iterator(SI));
160e245af65SOwen Anderson }
161e245af65SOwen Anderson 
162e245af65SOwen Anderson void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
163e245af65SOwen Anderson   delete unwrap(SI);
164e245af65SOwen Anderson }
165e245af65SOwen Anderson 
166e245af65SOwen Anderson LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
167e245af65SOwen Anderson                                        LLVMRelocationIteratorRef SI) {
168e245af65SOwen Anderson   return (*unwrap(SI) == (*unwrap(Section))->end_relocations()) ? 1 : 0;
169e245af65SOwen Anderson }
170e245af65SOwen Anderson 
171e245af65SOwen Anderson void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
172e245af65SOwen Anderson   error_code ec;
173e245af65SOwen Anderson   unwrap(SI)->increment(ec);
174e245af65SOwen Anderson   if (ec) report_fatal_error("LLVMMoveToNextRelocation failed: " +
175e245af65SOwen Anderson                              ec.message());
176e245af65SOwen Anderson }
177e245af65SOwen Anderson 
178e245af65SOwen Anderson 
179f239db40SOwen Anderson // SymbolRef accessors
180f239db40SOwen Anderson const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
181f239db40SOwen Anderson   StringRef ret;
182f239db40SOwen Anderson   if (error_code ec = (*unwrap(SI))->getName(ret))
183f239db40SOwen Anderson     report_fatal_error(ec.message());
184f239db40SOwen Anderson   return ret.data();
185f239db40SOwen Anderson }
186f239db40SOwen Anderson 
187f239db40SOwen Anderson uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
188f239db40SOwen Anderson   uint64_t ret;
189f239db40SOwen Anderson   if (error_code ec = (*unwrap(SI))->getAddress(ret))
190f239db40SOwen Anderson     report_fatal_error(ec.message());
191f239db40SOwen Anderson   return ret;
192f239db40SOwen Anderson }
193f239db40SOwen Anderson 
194cbe72fc9SDanil Malyshev uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI) {
195f239db40SOwen Anderson   uint64_t ret;
196cbe72fc9SDanil Malyshev   if (error_code ec = (*unwrap(SI))->getFileOffset(ret))
197f239db40SOwen Anderson     report_fatal_error(ec.message());
198f239db40SOwen Anderson   return ret;
199f239db40SOwen Anderson }
200f239db40SOwen Anderson 
201f239db40SOwen Anderson uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
202f239db40SOwen Anderson   uint64_t ret;
203f239db40SOwen Anderson   if (error_code ec = (*unwrap(SI))->getSize(ret))
204f239db40SOwen Anderson     report_fatal_error(ec.message());
205f239db40SOwen Anderson   return ret;
206f239db40SOwen Anderson }
207f239db40SOwen Anderson 
208f7a89d06SOwen Anderson // RelocationRef accessors
209f7a89d06SOwen Anderson uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) {
210f7a89d06SOwen Anderson   uint64_t ret;
211f7a89d06SOwen Anderson   if (error_code ec = (*unwrap(RI))->getAddress(ret))
212f7a89d06SOwen Anderson     report_fatal_error(ec.message());
213f7a89d06SOwen Anderson   return ret;
214f7a89d06SOwen Anderson }
215f7a89d06SOwen Anderson 
216cbe72fc9SDanil Malyshev uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
217cbe72fc9SDanil Malyshev   uint64_t ret;
218cbe72fc9SDanil Malyshev   if (error_code ec = (*unwrap(RI))->getOffset(ret))
219cbe72fc9SDanil Malyshev     report_fatal_error(ec.message());
220cbe72fc9SDanil Malyshev   return ret;
221cbe72fc9SDanil Malyshev }
222cbe72fc9SDanil Malyshev 
223f7a89d06SOwen Anderson LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
224806f0064SRafael Espindola   symbol_iterator ret = (*unwrap(RI))->getSymbol();
225f7a89d06SOwen Anderson   return wrap(new symbol_iterator(ret));
226f7a89d06SOwen Anderson }
227f7a89d06SOwen Anderson 
228f7a89d06SOwen Anderson uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
229f7a89d06SOwen Anderson   uint64_t ret;
230f7a89d06SOwen Anderson   if (error_code ec = (*unwrap(RI))->getType(ret))
231f7a89d06SOwen Anderson     report_fatal_error(ec.message());
232f7a89d06SOwen Anderson   return ret;
233f7a89d06SOwen Anderson }
234f7a89d06SOwen Anderson 
235f7a89d06SOwen Anderson // NOTE: Caller takes ownership of returned string.
236f7a89d06SOwen Anderson const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
237f7a89d06SOwen Anderson   SmallVector<char, 0> ret;
238f7a89d06SOwen Anderson   if (error_code ec = (*unwrap(RI))->getTypeName(ret))
239f7a89d06SOwen Anderson     report_fatal_error(ec.message());
240f7a89d06SOwen Anderson 
241f7a89d06SOwen Anderson   char *str = static_cast<char*>(malloc(ret.size()));
242f7a89d06SOwen Anderson   std::copy(ret.begin(), ret.end(), str);
243f7a89d06SOwen Anderson   return str;
244f7a89d06SOwen Anderson }
245f7a89d06SOwen Anderson 
246f7a89d06SOwen Anderson // NOTE: Caller takes ownership of returned string.
247f7a89d06SOwen Anderson const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
248f7a89d06SOwen Anderson   SmallVector<char, 0> ret;
249f7a89d06SOwen Anderson   if (error_code ec = (*unwrap(RI))->getValueString(ret))
250f7a89d06SOwen Anderson     report_fatal_error(ec.message());
251f7a89d06SOwen Anderson 
252f7a89d06SOwen Anderson   char *str = static_cast<char*>(malloc(ret.size()));
253f7a89d06SOwen Anderson   std::copy(ret.begin(), ret.end(), str);
254f7a89d06SOwen Anderson   return str;
255f7a89d06SOwen Anderson }
256f7a89d06SOwen Anderson 
257