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