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 report_fatal_error(Twine(OS.str())); 226 } 227 *unwrap(Sect) = *SecOrErr; 228 } 229 230 // ObjectFile Symbol iterators 231 LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { 232 OwningBinary<ObjectFile> *OB = unwrap(OF); 233 symbol_iterator SI = OB->getBinary()->symbol_begin(); 234 return wrap(new symbol_iterator(SI)); 235 } 236 237 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 238 delete unwrap(SI); 239 } 240 241 LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, 242 LLVMSymbolIteratorRef SI) { 243 OwningBinary<ObjectFile> *OB = unwrap(OF); 244 return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; 245 } 246 247 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 248 ++(*unwrap(SI)); 249 } 250 251 // SectionRef accessors 252 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 253 auto NameOrErr = (*unwrap(SI))->getName(); 254 if (!NameOrErr) 255 report_fatal_error(NameOrErr.takeError()); 256 return NameOrErr->data(); 257 } 258 259 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 260 return (*unwrap(SI))->getSize(); 261 } 262 263 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 264 if (Expected<StringRef> E = (*unwrap(SI))->getContents()) 265 return E->data(); 266 else 267 report_fatal_error(E.takeError()); 268 } 269 270 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 271 return (*unwrap(SI))->getAddress(); 272 } 273 274 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 275 LLVMSymbolIteratorRef Sym) { 276 return (*unwrap(SI))->containsSymbol(**unwrap(Sym)); 277 } 278 279 // Section Relocation iterators 280 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 281 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 282 return wrap(new relocation_iterator(SI)); 283 } 284 285 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 286 delete unwrap(SI); 287 } 288 289 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 290 LLVMRelocationIteratorRef SI) { 291 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 292 } 293 294 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 295 ++(*unwrap(SI)); 296 } 297 298 299 // SymbolRef accessors 300 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 301 Expected<StringRef> Ret = (*unwrap(SI))->getName(); 302 if (!Ret) { 303 std::string Buf; 304 raw_string_ostream OS(Buf); 305 logAllUnhandledErrors(Ret.takeError(), OS); 306 report_fatal_error(Twine(OS.str())); 307 } 308 return Ret->data(); 309 } 310 311 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 312 Expected<uint64_t> Ret = (*unwrap(SI))->getAddress(); 313 if (!Ret) { 314 std::string Buf; 315 raw_string_ostream OS(Buf); 316 logAllUnhandledErrors(Ret.takeError(), OS); 317 report_fatal_error(Twine(OS.str())); 318 } 319 return *Ret; 320 } 321 322 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 323 return (*unwrap(SI))->getCommonSize(); 324 } 325 326 // RelocationRef accessors 327 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 328 return (*unwrap(RI))->getOffset(); 329 } 330 331 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 332 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 333 return wrap(new symbol_iterator(ret)); 334 } 335 336 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 337 return (*unwrap(RI))->getType(); 338 } 339 340 // NOTE: Caller takes ownership of returned string. 341 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 342 SmallVector<char, 0> ret; 343 (*unwrap(RI))->getTypeName(ret); 344 char *str = static_cast<char*>(safe_malloc(ret.size())); 345 llvm::copy(ret, str); 346 return str; 347 } 348 349 // NOTE: Caller takes ownership of returned string. 350 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 351 return strdup(""); 352 } 353 354