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