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