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 
2248af1c2aSRafael Espindola inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
2348af1c2aSRafael Espindola   return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
2404d4e931SEric Christopher }
2504d4e931SEric Christopher 
2648af1c2aSRafael Espindola inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
2748af1c2aSRafael Espindola   return reinterpret_cast<LLVMObjectFileRef>(
2848af1c2aSRafael Espindola       const_cast<OwningBinary<ObjectFile> *>(OF));
2904d4e931SEric Christopher }
3004d4e931SEric Christopher 
3104d4e931SEric Christopher inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
3204d4e931SEric Christopher   return reinterpret_cast<section_iterator*>(SI);
3304d4e931SEric Christopher }
3404d4e931SEric Christopher 
3504d4e931SEric Christopher inline LLVMSectionIteratorRef
3604d4e931SEric Christopher wrap(const section_iterator *SI) {
3704d4e931SEric Christopher   return reinterpret_cast<LLVMSectionIteratorRef>
3804d4e931SEric Christopher     (const_cast<section_iterator*>(SI));
3904d4e931SEric Christopher }
4004d4e931SEric Christopher 
4104d4e931SEric Christopher inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
4204d4e931SEric Christopher   return reinterpret_cast<symbol_iterator*>(SI);
4304d4e931SEric Christopher }
4404d4e931SEric Christopher 
4504d4e931SEric Christopher inline LLVMSymbolIteratorRef
4604d4e931SEric Christopher wrap(const symbol_iterator *SI) {
4704d4e931SEric Christopher   return reinterpret_cast<LLVMSymbolIteratorRef>
4804d4e931SEric Christopher     (const_cast<symbol_iterator*>(SI));
4904d4e931SEric Christopher }
5004d4e931SEric Christopher 
5104d4e931SEric Christopher inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
5204d4e931SEric Christopher   return reinterpret_cast<relocation_iterator*>(SI);
5304d4e931SEric Christopher }
5404d4e931SEric Christopher 
5504d4e931SEric Christopher inline LLVMRelocationIteratorRef
5604d4e931SEric Christopher wrap(const relocation_iterator *SI) {
5704d4e931SEric Christopher   return reinterpret_cast<LLVMRelocationIteratorRef>
5804d4e931SEric Christopher     (const_cast<relocation_iterator*>(SI));
5904d4e931SEric Christopher }
6004d4e931SEric Christopher 
61f239db40SOwen Anderson // ObjectFile creation
62c56d2e8fSEric Christopher LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
636304e941SRafael Espindola   std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
64*3fcdf6aeSKevin Enderby   Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
6548af1c2aSRafael Espindola       ObjectFile::createObjectFile(Buf->getMemBufferRef()));
6648af1c2aSRafael Espindola   std::unique_ptr<ObjectFile> Obj;
67*3fcdf6aeSKevin Enderby   if (!ObjOrErr) {
68*3fcdf6aeSKevin Enderby     // TODO: Actually report errors helpfully.
69*3fcdf6aeSKevin Enderby     consumeError(ObjOrErr.takeError());
705a121b2eSBjorn Steinbrink     return nullptr;
71*3fcdf6aeSKevin Enderby   }
725a121b2eSBjorn Steinbrink 
735a121b2eSBjorn Steinbrink   auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
7448af1c2aSRafael Espindola   return wrap(Ret);
75c56d2e8fSEric Christopher }
76c56d2e8fSEric Christopher 
77c56d2e8fSEric Christopher void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
78c56d2e8fSEric Christopher   delete unwrap(ObjectFile);
79c56d2e8fSEric Christopher }
80c56d2e8fSEric Christopher 
81f239db40SOwen Anderson // ObjectFile Section iterators
8248af1c2aSRafael Espindola LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
8348af1c2aSRafael Espindola   OwningBinary<ObjectFile> *OB = unwrap(OF);
8448af1c2aSRafael Espindola   section_iterator SI = OB->getBinary()->section_begin();
85e5fd0047SMichael J. Spencer   return wrap(new section_iterator(SI));
86c56d2e8fSEric Christopher }
87c56d2e8fSEric Christopher 
88c56d2e8fSEric Christopher void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
89c56d2e8fSEric Christopher   delete unwrap(SI);
90c56d2e8fSEric Christopher }
91c56d2e8fSEric Christopher 
9248af1c2aSRafael Espindola LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
93c56d2e8fSEric Christopher                                     LLVMSectionIteratorRef SI) {
9448af1c2aSRafael Espindola   OwningBinary<ObjectFile> *OB = unwrap(OF);
9548af1c2aSRafael Espindola   return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
96c56d2e8fSEric Christopher }
97c56d2e8fSEric Christopher 
98c56d2e8fSEric Christopher void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
995e812afaSRafael Espindola   ++(*unwrap(SI));
100c56d2e8fSEric Christopher }
101c56d2e8fSEric Christopher 
10207bfdbb2SOwen Anderson void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
10307bfdbb2SOwen Anderson                                  LLVMSymbolIteratorRef Sym) {
1048bab889bSRafael Espindola   ErrorOr<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
1058bab889bSRafael Espindola   if (std::error_code ec = SecOrErr.getError())
10607bfdbb2SOwen Anderson     report_fatal_error(ec.message());
1078bab889bSRafael Espindola   *unwrap(Sect) = *SecOrErr;
10807bfdbb2SOwen Anderson }
10907bfdbb2SOwen Anderson 
110f239db40SOwen Anderson // ObjectFile Symbol iterators
11148af1c2aSRafael Espindola LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
11248af1c2aSRafael Espindola   OwningBinary<ObjectFile> *OB = unwrap(OF);
11348af1c2aSRafael Espindola   symbol_iterator SI = OB->getBinary()->symbol_begin();
114f239db40SOwen Anderson   return wrap(new symbol_iterator(SI));
115f239db40SOwen Anderson }
116f239db40SOwen Anderson 
117f239db40SOwen Anderson void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
118f239db40SOwen Anderson   delete unwrap(SI);
119f239db40SOwen Anderson }
120f239db40SOwen Anderson 
12148af1c2aSRafael Espindola LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
122f239db40SOwen Anderson                                    LLVMSymbolIteratorRef SI) {
12348af1c2aSRafael Espindola   OwningBinary<ObjectFile> *OB = unwrap(OF);
12448af1c2aSRafael Espindola   return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
125f239db40SOwen Anderson }
126f239db40SOwen Anderson 
127f239db40SOwen Anderson void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
1285e812afaSRafael Espindola   ++(*unwrap(SI));
129f239db40SOwen Anderson }
130f239db40SOwen Anderson 
131f239db40SOwen Anderson // SectionRef accessors
132c56d2e8fSEric Christopher const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
1331d6167fdSMichael J. Spencer   StringRef ret;
134db4ed0bdSRafael Espindola   if (std::error_code ec = (*unwrap(SI))->getName(ret))
1351d6167fdSMichael J. Spencer    report_fatal_error(ec.message());
1361d6167fdSMichael J. Spencer   return ret.data();
137c56d2e8fSEric Christopher }
138c56d2e8fSEric Christopher 
139c56d2e8fSEric Christopher uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
14080291274SRafael Espindola   return (*unwrap(SI))->getSize();
141c56d2e8fSEric Christopher }
142c56d2e8fSEric Christopher 
143c56d2e8fSEric Christopher const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
1441d6167fdSMichael J. Spencer   StringRef ret;
145db4ed0bdSRafael Espindola   if (std::error_code ec = (*unwrap(SI))->getContents(ret))
1461d6167fdSMichael J. Spencer     report_fatal_error(ec.message());
1471d6167fdSMichael J. Spencer   return ret.data();
148c56d2e8fSEric Christopher }
149f239db40SOwen Anderson 
150f239db40SOwen Anderson uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
15180291274SRafael Espindola   return (*unwrap(SI))->getAddress();
152f239db40SOwen Anderson }
153f239db40SOwen Anderson 
154500ebeb8SOwen Anderson LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
155f239db40SOwen Anderson                                  LLVMSymbolIteratorRef Sym) {
15680291274SRafael Espindola   return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
157f239db40SOwen Anderson }
158f239db40SOwen Anderson 
159e245af65SOwen Anderson // Section Relocation iterators
160e245af65SOwen Anderson LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
161b5155a57SRafael Espindola   relocation_iterator SI = (*unwrap(Section))->relocation_begin();
162e245af65SOwen Anderson   return wrap(new relocation_iterator(SI));
163e245af65SOwen Anderson }
164e245af65SOwen Anderson 
165e245af65SOwen Anderson void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
166e245af65SOwen Anderson   delete unwrap(SI);
167e245af65SOwen Anderson }
168e245af65SOwen Anderson 
169e245af65SOwen Anderson LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
170e245af65SOwen Anderson                                        LLVMRelocationIteratorRef SI) {
171b5155a57SRafael Espindola   return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
172e245af65SOwen Anderson }
173e245af65SOwen Anderson 
174e245af65SOwen Anderson void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
1755e812afaSRafael Espindola   ++(*unwrap(SI));
176e245af65SOwen Anderson }
177e245af65SOwen Anderson 
178e245af65SOwen Anderson 
179f239db40SOwen Anderson // SymbolRef accessors
180f239db40SOwen Anderson const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
1815d0c2ffaSRafael Espindola   ErrorOr<StringRef> Ret = (*unwrap(SI))->getName();
1825d0c2ffaSRafael Espindola   if (std::error_code EC = Ret.getError())
1835d0c2ffaSRafael Espindola     report_fatal_error(EC.message());
1845d0c2ffaSRafael Espindola   return Ret->data();
185f239db40SOwen Anderson }
186f239db40SOwen Anderson 
187f239db40SOwen Anderson uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
188ed067c45SRafael Espindola   ErrorOr<uint64_t> Ret = (*unwrap(SI))->getAddress();
189ed067c45SRafael Espindola   if (std::error_code EC = Ret.getError())
190ed067c45SRafael Espindola     report_fatal_error(EC.message());
191ed067c45SRafael Espindola   return *Ret;
192f239db40SOwen Anderson }
193f239db40SOwen Anderson 
194f239db40SOwen Anderson uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
195d7a32ea4SRafael Espindola   return (*unwrap(SI))->getCommonSize();
196f239db40SOwen Anderson }
197f239db40SOwen Anderson 
198f7a89d06SOwen Anderson // RelocationRef accessors
199cbe72fc9SDanil Malyshev uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
20096d071cdSRafael Espindola   return (*unwrap(RI))->getOffset();
201cbe72fc9SDanil Malyshev }
202cbe72fc9SDanil Malyshev 
203f7a89d06SOwen Anderson LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
204806f0064SRafael Espindola   symbol_iterator ret = (*unwrap(RI))->getSymbol();
205f7a89d06SOwen Anderson   return wrap(new symbol_iterator(ret));
206f7a89d06SOwen Anderson }
207f7a89d06SOwen Anderson 
208f7a89d06SOwen Anderson uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
20999c041b7SRafael Espindola   return (*unwrap(RI))->getType();
210f7a89d06SOwen Anderson }
211f7a89d06SOwen Anderson 
212f7a89d06SOwen Anderson // NOTE: Caller takes ownership of returned string.
213f7a89d06SOwen Anderson const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
214f7a89d06SOwen Anderson   SmallVector<char, 0> ret;
21541bb4325SRafael Espindola   (*unwrap(RI))->getTypeName(ret);
216f7a89d06SOwen Anderson   char *str = static_cast<char*>(malloc(ret.size()));
217f7a89d06SOwen Anderson   std::copy(ret.begin(), ret.end(), str);
218f7a89d06SOwen Anderson   return str;
219f7a89d06SOwen Anderson }
220f7a89d06SOwen Anderson 
221f7a89d06SOwen Anderson // NOTE: Caller takes ownership of returned string.
222f7a89d06SOwen Anderson const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
22337070a5aSRafael Espindola   return strdup("");
224f7a89d06SOwen Anderson }
225f7a89d06SOwen Anderson 
226