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