13b0f4066SDimitry Andric //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
23b0f4066SDimitry Andric //
33b0f4066SDimitry Andric //                     The LLVM Compiler Infrastructure
43b0f4066SDimitry Andric //
53b0f4066SDimitry Andric // This file is distributed under the University of Illinois Open Source
63b0f4066SDimitry Andric // License. See LICENSE.TXT for details.
73b0f4066SDimitry Andric //
83b0f4066SDimitry Andric //===----------------------------------------------------------------------===//
93b0f4066SDimitry Andric //
103b0f4066SDimitry Andric // This file defines the C bindings to the file-format-independent object
113b0f4066SDimitry Andric // library.
123b0f4066SDimitry Andric //
133b0f4066SDimitry Andric //===----------------------------------------------------------------------===//
143b0f4066SDimitry Andric 
153b0f4066SDimitry Andric #include "llvm-c/Object.h"
16db17bf38SDimitry Andric #include "llvm/ADT/SmallVector.h"
1791bc56edSDimitry Andric #include "llvm/Object/ObjectFile.h"
183b0f4066SDimitry Andric 
193b0f4066SDimitry Andric using namespace llvm;
203b0f4066SDimitry Andric using namespace object;
213b0f4066SDimitry Andric 
unwrap(LLVMObjectFileRef OF)2239d628a0SDimitry Andric inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
2339d628a0SDimitry Andric   return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
24284c1978SDimitry Andric }
25284c1978SDimitry Andric 
wrap(const OwningBinary<ObjectFile> * OF)2639d628a0SDimitry Andric inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
2739d628a0SDimitry Andric   return reinterpret_cast<LLVMObjectFileRef>(
2839d628a0SDimitry Andric       const_cast<OwningBinary<ObjectFile> *>(OF));
29284c1978SDimitry Andric }
30284c1978SDimitry Andric 
unwrap(LLVMSectionIteratorRef SI)31284c1978SDimitry Andric inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
32284c1978SDimitry Andric   return reinterpret_cast<section_iterator*>(SI);
33284c1978SDimitry Andric }
34284c1978SDimitry Andric 
35284c1978SDimitry Andric inline LLVMSectionIteratorRef
wrap(const section_iterator * SI)36284c1978SDimitry Andric wrap(const section_iterator *SI) {
37284c1978SDimitry Andric   return reinterpret_cast<LLVMSectionIteratorRef>
38284c1978SDimitry Andric     (const_cast<section_iterator*>(SI));
39284c1978SDimitry Andric }
40284c1978SDimitry Andric 
unwrap(LLVMSymbolIteratorRef SI)41284c1978SDimitry Andric inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
42284c1978SDimitry Andric   return reinterpret_cast<symbol_iterator*>(SI);
43284c1978SDimitry Andric }
44284c1978SDimitry Andric 
45284c1978SDimitry Andric inline LLVMSymbolIteratorRef
wrap(const symbol_iterator * SI)46284c1978SDimitry Andric wrap(const symbol_iterator *SI) {
47284c1978SDimitry Andric   return reinterpret_cast<LLVMSymbolIteratorRef>
48284c1978SDimitry Andric     (const_cast<symbol_iterator*>(SI));
49284c1978SDimitry Andric }
50284c1978SDimitry Andric 
unwrap(LLVMRelocationIteratorRef SI)51284c1978SDimitry Andric inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
52284c1978SDimitry Andric   return reinterpret_cast<relocation_iterator*>(SI);
53284c1978SDimitry Andric }
54284c1978SDimitry Andric 
55284c1978SDimitry Andric inline LLVMRelocationIteratorRef
wrap(const relocation_iterator * SI)56284c1978SDimitry Andric wrap(const relocation_iterator *SI) {
57284c1978SDimitry Andric   return reinterpret_cast<LLVMRelocationIteratorRef>
58284c1978SDimitry Andric     (const_cast<relocation_iterator*>(SI));
59284c1978SDimitry Andric }
60284c1978SDimitry Andric 
61dff0c46cSDimitry Andric // ObjectFile creation
LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf)623b0f4066SDimitry Andric LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
6391bc56edSDimitry Andric   std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
643ca95b02SDimitry Andric   Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
6539d628a0SDimitry Andric       ObjectFile::createObjectFile(Buf->getMemBufferRef()));
6639d628a0SDimitry Andric   std::unique_ptr<ObjectFile> Obj;
673ca95b02SDimitry Andric   if (!ObjOrErr) {
683ca95b02SDimitry Andric     // TODO: Actually report errors helpfully.
693ca95b02SDimitry Andric     consumeError(ObjOrErr.takeError());
7039d628a0SDimitry Andric     return nullptr;
713ca95b02SDimitry Andric   }
7239d628a0SDimitry Andric 
7339d628a0SDimitry Andric   auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
7439d628a0SDimitry Andric   return wrap(Ret);
753b0f4066SDimitry Andric }
763b0f4066SDimitry Andric 
LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile)773b0f4066SDimitry Andric void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
783b0f4066SDimitry Andric   delete unwrap(ObjectFile);
793b0f4066SDimitry Andric }
803b0f4066SDimitry Andric 
81dff0c46cSDimitry Andric // ObjectFile Section iterators
LLVMGetSections(LLVMObjectFileRef OF)8239d628a0SDimitry Andric LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
8339d628a0SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
8439d628a0SDimitry Andric   section_iterator SI = OB->getBinary()->section_begin();
856122f3e6SDimitry Andric   return wrap(new section_iterator(SI));
863b0f4066SDimitry Andric }
873b0f4066SDimitry Andric 
LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI)883b0f4066SDimitry Andric void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
893b0f4066SDimitry Andric   delete unwrap(SI);
903b0f4066SDimitry Andric }
913b0f4066SDimitry Andric 
LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,LLVMSectionIteratorRef SI)9239d628a0SDimitry Andric LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
933b0f4066SDimitry Andric                                     LLVMSectionIteratorRef SI) {
9439d628a0SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
9539d628a0SDimitry Andric   return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
963b0f4066SDimitry Andric }
973b0f4066SDimitry Andric 
LLVMMoveToNextSection(LLVMSectionIteratorRef SI)983b0f4066SDimitry Andric void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
9991bc56edSDimitry Andric   ++(*unwrap(SI));
1003b0f4066SDimitry Andric }
1013b0f4066SDimitry Andric 
LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,LLVMSymbolIteratorRef Sym)102dff0c46cSDimitry Andric void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
103dff0c46cSDimitry Andric                                  LLVMSymbolIteratorRef Sym) {
1043ca95b02SDimitry Andric   Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
1053ca95b02SDimitry Andric   if (!SecOrErr) {
1063ca95b02SDimitry Andric    std::string Buf;
1073ca95b02SDimitry Andric    raw_string_ostream OS(Buf);
108*b5893f02SDimitry Andric    logAllUnhandledErrors(SecOrErr.takeError(), OS);
1093ca95b02SDimitry Andric    OS.flush();
1103ca95b02SDimitry Andric    report_fatal_error(Buf);
1113ca95b02SDimitry Andric   }
1127d523365SDimitry Andric   *unwrap(Sect) = *SecOrErr;
113dff0c46cSDimitry Andric }
114dff0c46cSDimitry Andric 
115dff0c46cSDimitry Andric // ObjectFile Symbol iterators
LLVMGetSymbols(LLVMObjectFileRef OF)11639d628a0SDimitry Andric LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
11739d628a0SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
11839d628a0SDimitry Andric   symbol_iterator SI = OB->getBinary()->symbol_begin();
119dff0c46cSDimitry Andric   return wrap(new symbol_iterator(SI));
120dff0c46cSDimitry Andric }
121dff0c46cSDimitry Andric 
LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI)122dff0c46cSDimitry Andric void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
123dff0c46cSDimitry Andric   delete unwrap(SI);
124dff0c46cSDimitry Andric }
125dff0c46cSDimitry Andric 
LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,LLVMSymbolIteratorRef SI)12639d628a0SDimitry Andric LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
127dff0c46cSDimitry Andric                                    LLVMSymbolIteratorRef SI) {
12839d628a0SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
12939d628a0SDimitry Andric   return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
130dff0c46cSDimitry Andric }
131dff0c46cSDimitry Andric 
LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI)132dff0c46cSDimitry Andric void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
13391bc56edSDimitry Andric   ++(*unwrap(SI));
134dff0c46cSDimitry Andric }
135dff0c46cSDimitry Andric 
136dff0c46cSDimitry Andric // SectionRef accessors
LLVMGetSectionName(LLVMSectionIteratorRef SI)1373b0f4066SDimitry Andric const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
13817a519f9SDimitry Andric   StringRef ret;
13991bc56edSDimitry Andric   if (std::error_code ec = (*unwrap(SI))->getName(ret))
14017a519f9SDimitry Andric    report_fatal_error(ec.message());
14117a519f9SDimitry Andric   return ret.data();
1423b0f4066SDimitry Andric }
1433b0f4066SDimitry Andric 
LLVMGetSectionSize(LLVMSectionIteratorRef SI)1443b0f4066SDimitry Andric uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
14539d628a0SDimitry Andric   return (*unwrap(SI))->getSize();
1463b0f4066SDimitry Andric }
1473b0f4066SDimitry Andric 
LLVMGetSectionContents(LLVMSectionIteratorRef SI)1483b0f4066SDimitry Andric const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
14917a519f9SDimitry Andric   StringRef ret;
15091bc56edSDimitry Andric   if (std::error_code ec = (*unwrap(SI))->getContents(ret))
15117a519f9SDimitry Andric     report_fatal_error(ec.message());
15217a519f9SDimitry Andric   return ret.data();
1533b0f4066SDimitry Andric }
154dff0c46cSDimitry Andric 
LLVMGetSectionAddress(LLVMSectionIteratorRef SI)155dff0c46cSDimitry Andric uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
15639d628a0SDimitry Andric   return (*unwrap(SI))->getAddress();
157dff0c46cSDimitry Andric }
158dff0c46cSDimitry Andric 
LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,LLVMSymbolIteratorRef Sym)159dff0c46cSDimitry Andric LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
160dff0c46cSDimitry Andric                                  LLVMSymbolIteratorRef Sym) {
16139d628a0SDimitry Andric   return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
162dff0c46cSDimitry Andric }
163dff0c46cSDimitry Andric 
164dff0c46cSDimitry Andric // Section Relocation iterators
LLVMGetRelocations(LLVMSectionIteratorRef Section)165dff0c46cSDimitry Andric LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
16691bc56edSDimitry Andric   relocation_iterator SI = (*unwrap(Section))->relocation_begin();
167dff0c46cSDimitry Andric   return wrap(new relocation_iterator(SI));
168dff0c46cSDimitry Andric }
169dff0c46cSDimitry Andric 
LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI)170dff0c46cSDimitry Andric void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
171dff0c46cSDimitry Andric   delete unwrap(SI);
172dff0c46cSDimitry Andric }
173dff0c46cSDimitry Andric 
LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,LLVMRelocationIteratorRef SI)174dff0c46cSDimitry Andric LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
175dff0c46cSDimitry Andric                                        LLVMRelocationIteratorRef SI) {
17691bc56edSDimitry Andric   return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
177dff0c46cSDimitry Andric }
178dff0c46cSDimitry Andric 
LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI)179dff0c46cSDimitry Andric void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
18091bc56edSDimitry Andric   ++(*unwrap(SI));
181dff0c46cSDimitry Andric }
182dff0c46cSDimitry Andric 
183dff0c46cSDimitry Andric 
184dff0c46cSDimitry Andric // SymbolRef accessors
LLVMGetSymbolName(LLVMSymbolIteratorRef SI)185dff0c46cSDimitry Andric const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
1863ca95b02SDimitry Andric   Expected<StringRef> Ret = (*unwrap(SI))->getName();
1873ca95b02SDimitry Andric   if (!Ret) {
1883ca95b02SDimitry Andric     std::string Buf;
1893ca95b02SDimitry Andric     raw_string_ostream OS(Buf);
190*b5893f02SDimitry Andric     logAllUnhandledErrors(Ret.takeError(), OS);
1913ca95b02SDimitry Andric     OS.flush();
1923ca95b02SDimitry Andric     report_fatal_error(Buf);
1933ca95b02SDimitry Andric   }
1943dac3a9bSDimitry Andric   return Ret->data();
195dff0c46cSDimitry Andric }
196dff0c46cSDimitry Andric 
LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI)197dff0c46cSDimitry Andric uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
1983ca95b02SDimitry Andric   Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
1993ca95b02SDimitry Andric   if (!Ret) {
2003ca95b02SDimitry Andric     std::string Buf;
2013ca95b02SDimitry Andric     raw_string_ostream OS(Buf);
202*b5893f02SDimitry Andric     logAllUnhandledErrors(Ret.takeError(), OS);
2033ca95b02SDimitry Andric     OS.flush();
2043ca95b02SDimitry Andric     report_fatal_error(Buf);
2053ca95b02SDimitry Andric   }
206875ed548SDimitry Andric   return *Ret;
207dff0c46cSDimitry Andric }
208dff0c46cSDimitry Andric 
LLVMGetSymbolSize(LLVMSymbolIteratorRef SI)209dff0c46cSDimitry Andric uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
2103dac3a9bSDimitry Andric   return (*unwrap(SI))->getCommonSize();
211dff0c46cSDimitry Andric }
212dff0c46cSDimitry Andric 
213dff0c46cSDimitry Andric // RelocationRef accessors
LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI)214dff0c46cSDimitry Andric uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
2153dac3a9bSDimitry Andric   return (*unwrap(RI))->getOffset();
216dff0c46cSDimitry Andric }
217dff0c46cSDimitry Andric 
LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI)218dff0c46cSDimitry Andric LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
219f785676fSDimitry Andric   symbol_iterator ret = (*unwrap(RI))->getSymbol();
220dff0c46cSDimitry Andric   return wrap(new symbol_iterator(ret));
221dff0c46cSDimitry Andric }
222dff0c46cSDimitry Andric 
LLVMGetRelocationType(LLVMRelocationIteratorRef RI)223dff0c46cSDimitry Andric uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
2243dac3a9bSDimitry Andric   return (*unwrap(RI))->getType();
225dff0c46cSDimitry Andric }
226dff0c46cSDimitry Andric 
227dff0c46cSDimitry Andric // NOTE: Caller takes ownership of returned string.
LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI)228dff0c46cSDimitry Andric const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
229dff0c46cSDimitry Andric   SmallVector<char, 0> ret;
2303dac3a9bSDimitry Andric   (*unwrap(RI))->getTypeName(ret);
2314ba319b5SDimitry Andric   char *str = static_cast<char*>(safe_malloc(ret.size()));
232*b5893f02SDimitry Andric   llvm::copy(ret, str);
233dff0c46cSDimitry Andric   return str;
234dff0c46cSDimitry Andric }
235dff0c46cSDimitry Andric 
236dff0c46cSDimitry Andric // NOTE: Caller takes ownership of returned string.
LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI)237dff0c46cSDimitry Andric const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
23897bc6c73SDimitry Andric   return strdup("");
239dff0c46cSDimitry Andric }
240dff0c46cSDimitry Andric 
241