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