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