1 //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the C bindings to the file-format-independent object 10 // library. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm-c/Object.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/IR/LLVMContext.h" 17 #include "llvm/Object/ObjectFile.h" 18 19 using namespace llvm; 20 using namespace object; 21 22 inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) { 23 return reinterpret_cast<OwningBinary<ObjectFile> *>(OF); 24 } 25 26 inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) { 27 return reinterpret_cast<LLVMObjectFileRef>( 28 const_cast<OwningBinary<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 /*--.. Operations on binary files ..........................................--*/ 62 63 LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf, 64 LLVMContextRef Context, 65 char **ErrorMessage) { 66 auto maybeContext = Context ? unwrap(Context) : nullptr; 67 Expected<std::unique_ptr<Binary>> ObjOrErr( 68 createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext)); 69 if (!ObjOrErr) { 70 *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str()); 71 return nullptr; 72 } 73 74 return wrap(ObjOrErr.get().release()); 75 } 76 77 LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) { 78 auto Buf = unwrap(BR)->getMemoryBufferRef(); 79 return wrap(llvm::MemoryBuffer::getMemBuffer( 80 Buf.getBuffer(), Buf.getBufferIdentifier(), 81 /*RequiresNullTerminator*/false).release()); 82 } 83 84 void LLVMDisposeBinary(LLVMBinaryRef BR) { 85 delete unwrap(BR); 86 } 87 88 LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) { 89 class BinaryTypeMapper final : public Binary { 90 public: 91 static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) { 92 switch (Kind) { 93 case ID_Archive: 94 return LLVMBinaryTypeArchive; 95 case ID_MachOUniversalBinary: 96 return LLVMBinaryTypeMachOUniversalBinary; 97 case ID_COFFImportFile: 98 return LLVMBinaryTypeCOFFImportFile; 99 case ID_IR: 100 return LLVMBinaryTypeIR; 101 case ID_WinRes: 102 return LLVMBinaryTypeWinRes; 103 case ID_COFF: 104 return LLVMBinaryTypeCOFF; 105 case ID_ELF32L: 106 return LLVMBinaryTypeELF32L; 107 case ID_ELF32B: 108 return LLVMBinaryTypeELF32B; 109 case ID_ELF64L: 110 return LLVMBinaryTypeELF64L; 111 case ID_ELF64B: 112 return LLVMBinaryTypeELF64B; 113 case ID_MachO32L: 114 return LLVMBinaryTypeMachO32L; 115 case ID_MachO32B: 116 return LLVMBinaryTypeMachO32B; 117 case ID_MachO64L: 118 return LLVMBinaryTypeMachO64L; 119 case ID_MachO64B: 120 return LLVMBinaryTypeMachO64B; 121 case ID_Wasm: 122 return LLVMBinaryTypeWasm; 123 case ID_StartObjects: 124 case ID_EndObjects: 125 llvm_unreachable("Marker types are not valid binary kinds!"); 126 default: 127 llvm_unreachable("Unknown binary kind!"); 128 } 129 } 130 }; 131 return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType()); 132 } 133 134 LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) { 135 auto OF = cast<ObjectFile>(unwrap(BR)); 136 auto sections = OF->sections(); 137 if (sections.begin() == sections.end()) 138 return nullptr; 139 return wrap(new section_iterator(sections.begin())); 140 } 141 142 LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR, 143 LLVMSectionIteratorRef SI) { 144 auto OF = cast<ObjectFile>(unwrap(BR)); 145 return (*unwrap(SI) == OF->section_end()) ? 1 : 0; 146 } 147 148 LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) { 149 auto OF = cast<ObjectFile>(unwrap(BR)); 150 auto symbols = OF->symbols(); 151 if (symbols.begin() == symbols.end()) 152 return nullptr; 153 return wrap(new symbol_iterator(symbols.begin())); 154 } 155 156 LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR, 157 LLVMSymbolIteratorRef SI) { 158 auto OF = cast<ObjectFile>(unwrap(BR)); 159 return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0; 160 } 161 162 // ObjectFile creation 163 LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { 164 std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf)); 165 Expected<std::unique_ptr<ObjectFile>> ObjOrErr( 166 ObjectFile::createObjectFile(Buf->getMemBufferRef())); 167 std::unique_ptr<ObjectFile> Obj; 168 if (!ObjOrErr) { 169 // TODO: Actually report errors helpfully. 170 consumeError(ObjOrErr.takeError()); 171 return nullptr; 172 } 173 174 auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf)); 175 return wrap(Ret); 176 } 177 178 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 179 delete unwrap(ObjectFile); 180 } 181 182 // ObjectFile Section iterators 183 LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { 184 OwningBinary<ObjectFile> *OB = unwrap(OF); 185 section_iterator SI = OB->getBinary()->section_begin(); 186 return wrap(new section_iterator(SI)); 187 } 188 189 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 190 delete unwrap(SI); 191 } 192 193 LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, 194 LLVMSectionIteratorRef SI) { 195 OwningBinary<ObjectFile> *OB = unwrap(OF); 196 return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; 197 } 198 199 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 200 ++(*unwrap(SI)); 201 } 202 203 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 204 LLVMSymbolIteratorRef Sym) { 205 Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); 206 if (!SecOrErr) { 207 std::string Buf; 208 raw_string_ostream OS(Buf); 209 logAllUnhandledErrors(SecOrErr.takeError(), OS); 210 OS.flush(); 211 report_fatal_error(Buf); 212 } 213 *unwrap(Sect) = *SecOrErr; 214 } 215 216 // ObjectFile Symbol iterators 217 LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { 218 OwningBinary<ObjectFile> *OB = unwrap(OF); 219 symbol_iterator SI = OB->getBinary()->symbol_begin(); 220 return wrap(new symbol_iterator(SI)); 221 } 222 223 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 224 delete unwrap(SI); 225 } 226 227 LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, 228 LLVMSymbolIteratorRef SI) { 229 OwningBinary<ObjectFile> *OB = unwrap(OF); 230 return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; 231 } 232 233 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 234 ++(*unwrap(SI)); 235 } 236 237 // SectionRef accessors 238 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 239 StringRef ret; 240 if (std::error_code ec = (*unwrap(SI))->getName(ret)) 241 report_fatal_error(ec.message()); 242 return ret.data(); 243 } 244 245 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 246 return (*unwrap(SI))->getSize(); 247 } 248 249 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 250 if (Expected<StringRef> E = (*unwrap(SI))->getContents()) 251 return E->data(); 252 else 253 report_fatal_error(E.takeError()); 254 } 255 256 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 257 return (*unwrap(SI))->getAddress(); 258 } 259 260 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 261 LLVMSymbolIteratorRef Sym) { 262 return (*unwrap(SI))->containsSymbol(**unwrap(Sym)); 263 } 264 265 // Section Relocation iterators 266 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 267 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 268 return wrap(new relocation_iterator(SI)); 269 } 270 271 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 272 delete unwrap(SI); 273 } 274 275 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 276 LLVMRelocationIteratorRef SI) { 277 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 278 } 279 280 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 281 ++(*unwrap(SI)); 282 } 283 284 285 // SymbolRef accessors 286 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 287 Expected<StringRef> Ret = (*unwrap(SI))->getName(); 288 if (!Ret) { 289 std::string Buf; 290 raw_string_ostream OS(Buf); 291 logAllUnhandledErrors(Ret.takeError(), OS); 292 OS.flush(); 293 report_fatal_error(Buf); 294 } 295 return Ret->data(); 296 } 297 298 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 299 Expected<uint64_t> Ret = (*unwrap(SI))->getAddress(); 300 if (!Ret) { 301 std::string Buf; 302 raw_string_ostream OS(Buf); 303 logAllUnhandledErrors(Ret.takeError(), OS); 304 OS.flush(); 305 report_fatal_error(Buf); 306 } 307 return *Ret; 308 } 309 310 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 311 return (*unwrap(SI))->getCommonSize(); 312 } 313 314 // RelocationRef accessors 315 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 316 return (*unwrap(RI))->getOffset(); 317 } 318 319 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 320 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 321 return wrap(new symbol_iterator(ret)); 322 } 323 324 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 325 return (*unwrap(RI))->getType(); 326 } 327 328 // NOTE: Caller takes ownership of returned string. 329 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 330 SmallVector<char, 0> ret; 331 (*unwrap(RI))->getTypeName(ret); 332 char *str = static_cast<char*>(safe_malloc(ret.size())); 333 llvm::copy(ret, str); 334 return str; 335 } 336 337 // NOTE: Caller takes ownership of returned string. 338 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 339 return strdup(""); 340 } 341 342