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