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 std::unique_ptr<ObjectFile> Obj; 186 if (!ObjOrErr) { 187 // TODO: Actually report errors helpfully. 188 consumeError(ObjOrErr.takeError()); 189 return nullptr; 190 } 191 192 auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf)); 193 return wrap(Ret); 194 } 195 196 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 197 delete unwrap(ObjectFile); 198 } 199 200 // ObjectFile Section iterators 201 LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { 202 OwningBinary<ObjectFile> *OB = unwrap(OF); 203 section_iterator SI = OB->getBinary()->section_begin(); 204 return wrap(new section_iterator(SI)); 205 } 206 207 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 208 delete unwrap(SI); 209 } 210 211 LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, 212 LLVMSectionIteratorRef SI) { 213 OwningBinary<ObjectFile> *OB = unwrap(OF); 214 return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; 215 } 216 217 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 218 ++(*unwrap(SI)); 219 } 220 221 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 222 LLVMSymbolIteratorRef Sym) { 223 Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); 224 if (!SecOrErr) { 225 std::string Buf; 226 raw_string_ostream OS(Buf); 227 logAllUnhandledErrors(SecOrErr.takeError(), OS); 228 report_fatal_error(Twine(OS.str())); 229 } 230 *unwrap(Sect) = *SecOrErr; 231 } 232 233 // ObjectFile Symbol iterators 234 LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { 235 OwningBinary<ObjectFile> *OB = unwrap(OF); 236 symbol_iterator SI = OB->getBinary()->symbol_begin(); 237 return wrap(new symbol_iterator(SI)); 238 } 239 240 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 241 delete unwrap(SI); 242 } 243 244 LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, 245 LLVMSymbolIteratorRef SI) { 246 OwningBinary<ObjectFile> *OB = unwrap(OF); 247 return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; 248 } 249 250 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 251 ++(*unwrap(SI)); 252 } 253 254 // SectionRef accessors 255 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 256 auto NameOrErr = (*unwrap(SI))->getName(); 257 if (!NameOrErr) 258 report_fatal_error(NameOrErr.takeError()); 259 return NameOrErr->data(); 260 } 261 262 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 263 return (*unwrap(SI))->getSize(); 264 } 265 266 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 267 if (Expected<StringRef> E = (*unwrap(SI))->getContents()) 268 return E->data(); 269 else 270 report_fatal_error(E.takeError()); 271 } 272 273 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 274 return (*unwrap(SI))->getAddress(); 275 } 276 277 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 278 LLVMSymbolIteratorRef Sym) { 279 return (*unwrap(SI))->containsSymbol(**unwrap(Sym)); 280 } 281 282 // Section Relocation iterators 283 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 284 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 285 return wrap(new relocation_iterator(SI)); 286 } 287 288 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 289 delete unwrap(SI); 290 } 291 292 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 293 LLVMRelocationIteratorRef SI) { 294 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 295 } 296 297 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 298 ++(*unwrap(SI)); 299 } 300 301 302 // SymbolRef accessors 303 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 304 Expected<StringRef> Ret = (*unwrap(SI))->getName(); 305 if (!Ret) { 306 std::string Buf; 307 raw_string_ostream OS(Buf); 308 logAllUnhandledErrors(Ret.takeError(), OS); 309 report_fatal_error(Twine(OS.str())); 310 } 311 return Ret->data(); 312 } 313 314 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 315 Expected<uint64_t> Ret = (*unwrap(SI))->getAddress(); 316 if (!Ret) { 317 std::string Buf; 318 raw_string_ostream OS(Buf); 319 logAllUnhandledErrors(Ret.takeError(), OS); 320 report_fatal_error(Twine(OS.str())); 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