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_Wasm: 124 return LLVMBinaryTypeWasm; 125 case ID_StartObjects: 126 case ID_EndObjects: 127 llvm_unreachable("Marker types are not valid binary kinds!"); 128 default: 129 llvm_unreachable("Unknown binary kind!"); 130 } 131 } 132 }; 133 return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType()); 134 } 135 136 LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR, 137 const char *Arch, 138 size_t ArchLen, 139 char **ErrorMessage) { 140 auto universal = cast<MachOUniversalBinary>(unwrap(BR)); 141 Expected<std::unique_ptr<ObjectFile>> ObjOrErr( 142 universal->getMachOObjectForArch({Arch, ArchLen})); 143 if (!ObjOrErr) { 144 *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str()); 145 return nullptr; 146 } 147 return wrap(ObjOrErr.get().release()); 148 } 149 150 LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) { 151 auto OF = cast<ObjectFile>(unwrap(BR)); 152 auto sections = OF->sections(); 153 if (sections.begin() == sections.end()) 154 return nullptr; 155 return wrap(new section_iterator(sections.begin())); 156 } 157 158 LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR, 159 LLVMSectionIteratorRef SI) { 160 auto OF = cast<ObjectFile>(unwrap(BR)); 161 return (*unwrap(SI) == OF->section_end()) ? 1 : 0; 162 } 163 164 LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) { 165 auto OF = cast<ObjectFile>(unwrap(BR)); 166 auto symbols = OF->symbols(); 167 if (symbols.begin() == symbols.end()) 168 return nullptr; 169 return wrap(new symbol_iterator(symbols.begin())); 170 } 171 172 LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR, 173 LLVMSymbolIteratorRef SI) { 174 auto OF = cast<ObjectFile>(unwrap(BR)); 175 return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0; 176 } 177 178 // ObjectFile creation 179 LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { 180 std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf)); 181 Expected<std::unique_ptr<ObjectFile>> ObjOrErr( 182 ObjectFile::createObjectFile(Buf->getMemBufferRef())); 183 std::unique_ptr<ObjectFile> Obj; 184 if (!ObjOrErr) { 185 // TODO: Actually report errors helpfully. 186 consumeError(ObjOrErr.takeError()); 187 return nullptr; 188 } 189 190 auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf)); 191 return wrap(Ret); 192 } 193 194 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 195 delete unwrap(ObjectFile); 196 } 197 198 // ObjectFile Section iterators 199 LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { 200 OwningBinary<ObjectFile> *OB = unwrap(OF); 201 section_iterator SI = OB->getBinary()->section_begin(); 202 return wrap(new section_iterator(SI)); 203 } 204 205 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 206 delete unwrap(SI); 207 } 208 209 LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, 210 LLVMSectionIteratorRef SI) { 211 OwningBinary<ObjectFile> *OB = unwrap(OF); 212 return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; 213 } 214 215 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 216 ++(*unwrap(SI)); 217 } 218 219 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 220 LLVMSymbolIteratorRef Sym) { 221 Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); 222 if (!SecOrErr) { 223 std::string Buf; 224 raw_string_ostream OS(Buf); 225 logAllUnhandledErrors(SecOrErr.takeError(), OS); 226 report_fatal_error(Twine(OS.str())); 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 report_fatal_error(Twine(OS.str())); 308 } 309 return Ret->data(); 310 } 311 312 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 313 Expected<uint64_t> Ret = (*unwrap(SI))->getAddress(); 314 if (!Ret) { 315 std::string Buf; 316 raw_string_ostream OS(Buf); 317 logAllUnhandledErrors(Ret.takeError(), OS); 318 report_fatal_error(Twine(OS.str())); 319 } 320 return *Ret; 321 } 322 323 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 324 return (*unwrap(SI))->getCommonSize(); 325 } 326 327 // RelocationRef accessors 328 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 329 return (*unwrap(RI))->getOffset(); 330 } 331 332 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 333 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 334 return wrap(new symbol_iterator(ret)); 335 } 336 337 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 338 return (*unwrap(RI))->getType(); 339 } 340 341 // NOTE: Caller takes ownership of returned string. 342 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 343 SmallVector<char, 0> ret; 344 (*unwrap(RI))->getTypeName(ret); 345 char *str = static_cast<char*>(safe_malloc(ret.size())); 346 llvm::copy(ret, str); 347 return str; 348 } 349 350 // NOTE: Caller takes ownership of returned string. 351 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 352 return strdup(""); 353 } 354 355