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/ADT/SmallVector.h" 16 #include "llvm-c/Object.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 LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { 63 std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf)); 64 Expected<std::unique_ptr<ObjectFile>> ObjOrErr( 65 ObjectFile::createObjectFile(Buf->getMemBufferRef())); 66 std::unique_ptr<ObjectFile> Obj; 67 if (!ObjOrErr) { 68 // TODO: Actually report errors helpfully. 69 consumeError(ObjOrErr.takeError()); 70 return nullptr; 71 } 72 73 auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf)); 74 return wrap(Ret); 75 } 76 77 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 78 delete unwrap(ObjectFile); 79 } 80 81 // ObjectFile Section iterators 82 LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { 83 OwningBinary<ObjectFile> *OB = unwrap(OF); 84 section_iterator SI = OB->getBinary()->section_begin(); 85 return wrap(new section_iterator(SI)); 86 } 87 88 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 89 delete unwrap(SI); 90 } 91 92 LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, 93 LLVMSectionIteratorRef SI) { 94 OwningBinary<ObjectFile> *OB = unwrap(OF); 95 return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; 96 } 97 98 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 99 ++(*unwrap(SI)); 100 } 101 102 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 103 LLVMSymbolIteratorRef Sym) { 104 ErrorOr<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); 105 if (std::error_code ec = SecOrErr.getError()) 106 report_fatal_error(ec.message()); 107 *unwrap(Sect) = *SecOrErr; 108 } 109 110 // ObjectFile Symbol iterators 111 LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { 112 OwningBinary<ObjectFile> *OB = unwrap(OF); 113 symbol_iterator SI = OB->getBinary()->symbol_begin(); 114 return wrap(new symbol_iterator(SI)); 115 } 116 117 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 118 delete unwrap(SI); 119 } 120 121 LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, 122 LLVMSymbolIteratorRef SI) { 123 OwningBinary<ObjectFile> *OB = unwrap(OF); 124 return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; 125 } 126 127 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 128 ++(*unwrap(SI)); 129 } 130 131 // SectionRef accessors 132 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 133 StringRef ret; 134 if (std::error_code ec = (*unwrap(SI))->getName(ret)) 135 report_fatal_error(ec.message()); 136 return ret.data(); 137 } 138 139 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 140 return (*unwrap(SI))->getSize(); 141 } 142 143 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 144 StringRef ret; 145 if (std::error_code ec = (*unwrap(SI))->getContents(ret)) 146 report_fatal_error(ec.message()); 147 return ret.data(); 148 } 149 150 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 151 return (*unwrap(SI))->getAddress(); 152 } 153 154 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 155 LLVMSymbolIteratorRef Sym) { 156 return (*unwrap(SI))->containsSymbol(**unwrap(Sym)); 157 } 158 159 // Section Relocation iterators 160 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 161 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 162 return wrap(new relocation_iterator(SI)); 163 } 164 165 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 166 delete unwrap(SI); 167 } 168 169 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 170 LLVMRelocationIteratorRef SI) { 171 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 172 } 173 174 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 175 ++(*unwrap(SI)); 176 } 177 178 179 // SymbolRef accessors 180 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 181 Expected<StringRef> Ret = (*unwrap(SI))->getName(); 182 if (!Ret) { 183 std::string Buf; 184 raw_string_ostream OS(Buf); 185 logAllUnhandledErrors(Ret.takeError(), OS, ""); 186 OS.flush(); 187 report_fatal_error(Buf); 188 } 189 return Ret->data(); 190 } 191 192 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 193 ErrorOr<uint64_t> Ret = (*unwrap(SI))->getAddress(); 194 if (std::error_code EC = Ret.getError()) 195 report_fatal_error(EC.message()); 196 return *Ret; 197 } 198 199 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 200 return (*unwrap(SI))->getCommonSize(); 201 } 202 203 // RelocationRef accessors 204 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 205 return (*unwrap(RI))->getOffset(); 206 } 207 208 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 209 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 210 return wrap(new symbol_iterator(ret)); 211 } 212 213 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 214 return (*unwrap(RI))->getType(); 215 } 216 217 // NOTE: Caller takes ownership of returned string. 218 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 219 SmallVector<char, 0> ret; 220 (*unwrap(RI))->getTypeName(ret); 221 char *str = static_cast<char*>(malloc(ret.size())); 222 std::copy(ret.begin(), ret.end(), str); 223 return str; 224 } 225 226 // NOTE: Caller takes ownership of returned string. 227 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 228 return strdup(""); 229 } 230 231