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() : nullptr; 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)->section_begin(); 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)->section_end()) ? 1 : 0; 84 } 85 86 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 87 ++(*unwrap(SI)); 88 } 89 90 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 91 LLVMSymbolIteratorRef Sym) { 92 if (std::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)->symbol_begin(); 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)->symbol_end()) ? 1 : 0; 109 } 110 111 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 112 ++(*unwrap(SI)); 113 } 114 115 // SectionRef accessors 116 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 117 StringRef ret; 118 if (std::error_code ec = (*unwrap(SI))->getName(ret)) 119 report_fatal_error(ec.message()); 120 return ret.data(); 121 } 122 123 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 124 uint64_t ret; 125 if (std::error_code ec = (*unwrap(SI))->getSize(ret)) 126 report_fatal_error(ec.message()); 127 return ret; 128 } 129 130 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 131 StringRef ret; 132 if (std::error_code ec = (*unwrap(SI))->getContents(ret)) 133 report_fatal_error(ec.message()); 134 return ret.data(); 135 } 136 137 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 138 uint64_t ret; 139 if (std::error_code ec = (*unwrap(SI))->getAddress(ret)) 140 report_fatal_error(ec.message()); 141 return ret; 142 } 143 144 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 145 LLVMSymbolIteratorRef Sym) { 146 bool ret; 147 if (std::error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret)) 148 report_fatal_error(ec.message()); 149 return ret; 150 } 151 152 // Section Relocation iterators 153 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 154 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 155 return wrap(new relocation_iterator(SI)); 156 } 157 158 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 159 delete unwrap(SI); 160 } 161 162 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 163 LLVMRelocationIteratorRef SI) { 164 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 165 } 166 167 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 168 ++(*unwrap(SI)); 169 } 170 171 172 // SymbolRef accessors 173 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 174 StringRef ret; 175 if (std::error_code ec = (*unwrap(SI))->getName(ret)) 176 report_fatal_error(ec.message()); 177 return ret.data(); 178 } 179 180 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 181 uint64_t ret; 182 if (std::error_code ec = (*unwrap(SI))->getAddress(ret)) 183 report_fatal_error(ec.message()); 184 return ret; 185 } 186 187 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 188 uint64_t ret; 189 if (std::error_code ec = (*unwrap(SI))->getSize(ret)) 190 report_fatal_error(ec.message()); 191 return ret; 192 } 193 194 // RelocationRef accessors 195 uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) { 196 uint64_t ret; 197 if (std::error_code ec = (*unwrap(RI))->getAddress(ret)) 198 report_fatal_error(ec.message()); 199 return ret; 200 } 201 202 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 203 uint64_t ret; 204 if (std::error_code ec = (*unwrap(RI))->getOffset(ret)) 205 report_fatal_error(ec.message()); 206 return ret; 207 } 208 209 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 210 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 211 return wrap(new symbol_iterator(ret)); 212 } 213 214 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 215 uint64_t ret; 216 if (std::error_code ec = (*unwrap(RI))->getType(ret)) 217 report_fatal_error(ec.message()); 218 return ret; 219 } 220 221 // NOTE: Caller takes ownership of returned string. 222 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 223 SmallVector<char, 0> ret; 224 if (std::error_code ec = (*unwrap(RI))->getTypeName(ret)) 225 report_fatal_error(ec.message()); 226 227 char *str = static_cast<char*>(malloc(ret.size())); 228 std::copy(ret.begin(), ret.end(), str); 229 return str; 230 } 231 232 // NOTE: Caller takes ownership of returned string. 233 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 234 SmallVector<char, 0> ret; 235 if (std::error_code ec = (*unwrap(RI))->getValueString(ret)) 236 report_fatal_error(ec.message()); 237 238 char *str = static_cast<char*>(malloc(ret.size())); 239 std::copy(ret.begin(), ret.end(), str); 240 return str; 241 } 242 243