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/Object/ObjectFile.h" 17 18 using namespace llvm; 19 using namespace object; 20 21 inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) { 22 return reinterpret_cast<OwningBinary<ObjectFile> *>(OF); 23 } 24 25 inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) { 26 return reinterpret_cast<LLVMObjectFileRef>( 27 const_cast<OwningBinary<ObjectFile> *>(OF)); 28 } 29 30 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { 31 return reinterpret_cast<section_iterator*>(SI); 32 } 33 34 inline LLVMSectionIteratorRef 35 wrap(const section_iterator *SI) { 36 return reinterpret_cast<LLVMSectionIteratorRef> 37 (const_cast<section_iterator*>(SI)); 38 } 39 40 inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) { 41 return reinterpret_cast<symbol_iterator*>(SI); 42 } 43 44 inline LLVMSymbolIteratorRef 45 wrap(const symbol_iterator *SI) { 46 return reinterpret_cast<LLVMSymbolIteratorRef> 47 (const_cast<symbol_iterator*>(SI)); 48 } 49 50 inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) { 51 return reinterpret_cast<relocation_iterator*>(SI); 52 } 53 54 inline LLVMRelocationIteratorRef 55 wrap(const relocation_iterator *SI) { 56 return reinterpret_cast<LLVMRelocationIteratorRef> 57 (const_cast<relocation_iterator*>(SI)); 58 } 59 60 // ObjectFile creation 61 LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) { 62 std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf)); 63 Expected<std::unique_ptr<ObjectFile>> ObjOrErr( 64 ObjectFile::createObjectFile(Buf->getMemBufferRef())); 65 std::unique_ptr<ObjectFile> Obj; 66 if (!ObjOrErr) { 67 // TODO: Actually report errors helpfully. 68 consumeError(ObjOrErr.takeError()); 69 return nullptr; 70 } 71 72 auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf)); 73 return wrap(Ret); 74 } 75 76 void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 77 delete unwrap(ObjectFile); 78 } 79 80 // ObjectFile Section iterators 81 LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { 82 OwningBinary<ObjectFile> *OB = unwrap(OF); 83 section_iterator SI = OB->getBinary()->section_begin(); 84 return wrap(new section_iterator(SI)); 85 } 86 87 void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 88 delete unwrap(SI); 89 } 90 91 LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, 92 LLVMSectionIteratorRef SI) { 93 OwningBinary<ObjectFile> *OB = unwrap(OF); 94 return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; 95 } 96 97 void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 98 ++(*unwrap(SI)); 99 } 100 101 void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 102 LLVMSymbolIteratorRef Sym) { 103 Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); 104 if (!SecOrErr) { 105 std::string Buf; 106 raw_string_ostream OS(Buf); 107 logAllUnhandledErrors(SecOrErr.takeError(), OS); 108 OS.flush(); 109 report_fatal_error(Buf); 110 } 111 *unwrap(Sect) = *SecOrErr; 112 } 113 114 // ObjectFile Symbol iterators 115 LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { 116 OwningBinary<ObjectFile> *OB = unwrap(OF); 117 symbol_iterator SI = OB->getBinary()->symbol_begin(); 118 return wrap(new symbol_iterator(SI)); 119 } 120 121 void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 122 delete unwrap(SI); 123 } 124 125 LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, 126 LLVMSymbolIteratorRef SI) { 127 OwningBinary<ObjectFile> *OB = unwrap(OF); 128 return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; 129 } 130 131 void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 132 ++(*unwrap(SI)); 133 } 134 135 // SectionRef accessors 136 const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 137 StringRef ret; 138 if (std::error_code ec = (*unwrap(SI))->getName(ret)) 139 report_fatal_error(ec.message()); 140 return ret.data(); 141 } 142 143 uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 144 return (*unwrap(SI))->getSize(); 145 } 146 147 const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 148 StringRef ret; 149 if (std::error_code ec = (*unwrap(SI))->getContents(ret)) 150 report_fatal_error(ec.message()); 151 return ret.data(); 152 } 153 154 uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 155 return (*unwrap(SI))->getAddress(); 156 } 157 158 LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 159 LLVMSymbolIteratorRef Sym) { 160 return (*unwrap(SI))->containsSymbol(**unwrap(Sym)); 161 } 162 163 // Section Relocation iterators 164 LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 165 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 166 return wrap(new relocation_iterator(SI)); 167 } 168 169 void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 170 delete unwrap(SI); 171 } 172 173 LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 174 LLVMRelocationIteratorRef SI) { 175 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 176 } 177 178 void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 179 ++(*unwrap(SI)); 180 } 181 182 183 // SymbolRef accessors 184 const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 185 Expected<StringRef> Ret = (*unwrap(SI))->getName(); 186 if (!Ret) { 187 std::string Buf; 188 raw_string_ostream OS(Buf); 189 logAllUnhandledErrors(Ret.takeError(), OS); 190 OS.flush(); 191 report_fatal_error(Buf); 192 } 193 return Ret->data(); 194 } 195 196 uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 197 Expected<uint64_t> Ret = (*unwrap(SI))->getAddress(); 198 if (!Ret) { 199 std::string Buf; 200 raw_string_ostream OS(Buf); 201 logAllUnhandledErrors(Ret.takeError(), OS); 202 OS.flush(); 203 report_fatal_error(Buf); 204 } 205 return *Ret; 206 } 207 208 uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 209 return (*unwrap(SI))->getCommonSize(); 210 } 211 212 // RelocationRef accessors 213 uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 214 return (*unwrap(RI))->getOffset(); 215 } 216 217 LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 218 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 219 return wrap(new symbol_iterator(ret)); 220 } 221 222 uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 223 return (*unwrap(RI))->getType(); 224 } 225 226 // NOTE: Caller takes ownership of returned string. 227 const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 228 SmallVector<char, 0> ret; 229 (*unwrap(RI))->getTypeName(ret); 230 char *str = static_cast<char*>(safe_malloc(ret.size())); 231 llvm::copy(ret, str); 232 return str; 233 } 234 235 // NOTE: Caller takes ownership of returned string. 236 const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 237 return strdup(""); 238 } 239 240