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