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