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 ObjectFile *unwrap(LLVMObjectFileRef OF) { 23 return reinterpret_cast<ObjectFile*>(OF); 24 } 25 26 inline LLVMObjectFileRef wrap(const ObjectFile *OF) { 27 return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF)); 28 } 29 30 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { 31 return reinterpret_cast<section_iterator*>(SI); 32 } 33 34 inline LLVMSectionIteratorRef 35 wrap(const section_iterator *SI) { 36 return reinterpret_cast<LLVMSectionIteratorRef> 37 (const_cast<section_iterator*>(SI)); 38 } 39 40 inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) { 41 return reinterpret_cast<symbol_iterator*>(SI); 42 } 43 44 inline LLVMSymbolIteratorRef 45 wrap(const symbol_iterator *SI) { 46 return reinterpret_cast<LLVMSymbolIteratorRef> 47 (const_cast<symbol_iterator*>(SI)); 48 } 49 50 inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) { 51 return reinterpret_cast<relocation_iterator*>(SI); 52 } 53 54 inline LLVMRelocationIteratorRef 55 wrap(const relocation_iterator *SI) { 56 return reinterpret_cast<LLVMRelocationIteratorRef> 57 (const_cast<relocation_iterator*>(SI)); 58 } 59 60 // ObjectFile creation 61 LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { 62 ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf))); 63 ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : 0; 64 return wrap(Obj); 65 } 66 67 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 68 delete unwrap(ObjectFile); 69 } 70 71 // ObjectFile Section iterators 72 LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) { 73 section_iterator SI = unwrap(ObjectFile)->begin_sections(); 74 return wrap(new section_iterator(SI)); 75 } 76 77 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 78 delete unwrap(SI); 79 } 80 81 LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile, 82 LLVMSectionIteratorRef SI) { 83 return (*unwrap(SI) == unwrap(ObjectFile)->end_sections()) ? 1 : 0; 84 } 85 86 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 87 error_code ec; 88 unwrap(SI)->increment(ec); 89 if (ec) report_fatal_error("LLVMMoveToNextSection failed: " + ec.message()); 90 } 91 92 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 93 LLVMSymbolIteratorRef Sym) { 94 if (error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect))) 95 report_fatal_error(ec.message()); 96 } 97 98 // ObjectFile Symbol iterators 99 LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) { 100 symbol_iterator SI = unwrap(ObjectFile)->begin_symbols(); 101 return wrap(new symbol_iterator(SI)); 102 } 103 104 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 105 delete unwrap(SI); 106 } 107 108 LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile, 109 LLVMSymbolIteratorRef SI) { 110 return (*unwrap(SI) == unwrap(ObjectFile)->end_symbols()) ? 1 : 0; 111 } 112 113 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 114 error_code ec; 115 unwrap(SI)->increment(ec); 116 if (ec) report_fatal_error("LLVMMoveToNextSymbol failed: " + ec.message()); 117 } 118 119 // SectionRef accessors 120 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 121 StringRef ret; 122 if (error_code ec = (*unwrap(SI))->getName(ret)) 123 report_fatal_error(ec.message()); 124 return ret.data(); 125 } 126 127 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 128 uint64_t ret; 129 if (error_code ec = (*unwrap(SI))->getSize(ret)) 130 report_fatal_error(ec.message()); 131 return ret; 132 } 133 134 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 135 StringRef ret; 136 if (error_code ec = (*unwrap(SI))->getContents(ret)) 137 report_fatal_error(ec.message()); 138 return ret.data(); 139 } 140 141 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 142 uint64_t ret; 143 if (error_code ec = (*unwrap(SI))->getAddress(ret)) 144 report_fatal_error(ec.message()); 145 return ret; 146 } 147 148 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 149 LLVMSymbolIteratorRef Sym) { 150 bool ret; 151 if (error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret)) 152 report_fatal_error(ec.message()); 153 return ret; 154 } 155 156 // Section Relocation iterators 157 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 158 relocation_iterator SI = (*unwrap(Section))->begin_relocations(); 159 return wrap(new relocation_iterator(SI)); 160 } 161 162 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 163 delete unwrap(SI); 164 } 165 166 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 167 LLVMRelocationIteratorRef SI) { 168 return (*unwrap(SI) == (*unwrap(Section))->end_relocations()) ? 1 : 0; 169 } 170 171 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 172 error_code ec; 173 unwrap(SI)->increment(ec); 174 if (ec) report_fatal_error("LLVMMoveToNextRelocation failed: " + 175 ec.message()); 176 } 177 178 179 // SymbolRef accessors 180 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 181 StringRef ret; 182 if (error_code ec = (*unwrap(SI))->getName(ret)) 183 report_fatal_error(ec.message()); 184 return ret.data(); 185 } 186 187 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 188 uint64_t ret; 189 if (error_code ec = (*unwrap(SI))->getAddress(ret)) 190 report_fatal_error(ec.message()); 191 return ret; 192 } 193 194 uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI) { 195 uint64_t ret; 196 if (error_code ec = (*unwrap(SI))->getFileOffset(ret)) 197 report_fatal_error(ec.message()); 198 return ret; 199 } 200 201 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 202 uint64_t ret; 203 if (error_code ec = (*unwrap(SI))->getSize(ret)) 204 report_fatal_error(ec.message()); 205 return ret; 206 } 207 208 // RelocationRef accessors 209 uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) { 210 uint64_t ret; 211 if (error_code ec = (*unwrap(RI))->getAddress(ret)) 212 report_fatal_error(ec.message()); 213 return ret; 214 } 215 216 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 217 uint64_t ret; 218 if (error_code ec = (*unwrap(RI))->getOffset(ret)) 219 report_fatal_error(ec.message()); 220 return ret; 221 } 222 223 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 224 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 225 return wrap(new symbol_iterator(ret)); 226 } 227 228 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 229 uint64_t ret; 230 if (error_code ec = (*unwrap(RI))->getType(ret)) 231 report_fatal_error(ec.message()); 232 return ret; 233 } 234 235 // NOTE: Caller takes ownership of returned string. 236 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 237 SmallVector<char, 0> ret; 238 if (error_code ec = (*unwrap(RI))->getTypeName(ret)) 239 report_fatal_error(ec.message()); 240 241 char *str = static_cast<char*>(malloc(ret.size())); 242 std::copy(ret.begin(), ret.end(), str); 243 return str; 244 } 245 246 // NOTE: Caller takes ownership of returned string. 247 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 248 SmallVector<char, 0> ret; 249 if (error_code ec = (*unwrap(RI))->getValueString(ret)) 250 report_fatal_error(ec.message()); 251 252 char *str = static_cast<char*>(malloc(ret.size())); 253 std::copy(ret.begin(), ret.end(), str); 254 return str; 255 } 256 257