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