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 ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr( 65 ObjectFile::createObjectFile(Buf->getMemBufferRef())); 66 std::unique_ptr<ObjectFile> Obj; 67 if (!ObjOrErr) 68 return nullptr; 69 70 auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf)); 71 return wrap(Ret); 72} 73 74void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { 75 delete unwrap(ObjectFile); 76} 77 78// ObjectFile Section iterators 79LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) { 80 OwningBinary<ObjectFile> *OB = unwrap(OF); 81 section_iterator SI = OB->getBinary()->section_begin(); 82 return wrap(new section_iterator(SI)); 83} 84 85void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { 86 delete unwrap(SI); 87} 88 89LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF, 90 LLVMSectionIteratorRef SI) { 91 OwningBinary<ObjectFile> *OB = unwrap(OF); 92 return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0; 93} 94 95void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) { 96 ++(*unwrap(SI)); 97} 98 99void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect, 100 LLVMSymbolIteratorRef Sym) { 101 ErrorOr<section_iterator> SecOrErr = (*unwrap(Sym))->getSection(); 102 if (std::error_code ec = SecOrErr.getError()) 103 report_fatal_error(ec.message()); 104 *unwrap(Sect) = *SecOrErr; 105} 106 107// ObjectFile Symbol iterators 108LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) { 109 OwningBinary<ObjectFile> *OB = unwrap(OF); 110 symbol_iterator SI = OB->getBinary()->symbol_begin(); 111 return wrap(new symbol_iterator(SI)); 112} 113 114void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) { 115 delete unwrap(SI); 116} 117 118LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF, 119 LLVMSymbolIteratorRef SI) { 120 OwningBinary<ObjectFile> *OB = unwrap(OF); 121 return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0; 122} 123 124void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) { 125 ++(*unwrap(SI)); 126} 127 128// SectionRef accessors 129const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) { 130 StringRef ret; 131 if (std::error_code ec = (*unwrap(SI))->getName(ret)) 132 report_fatal_error(ec.message()); 133 return ret.data(); 134} 135 136uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) { 137 return (*unwrap(SI))->getSize(); 138} 139 140const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) { 141 StringRef ret; 142 if (std::error_code ec = (*unwrap(SI))->getContents(ret)) 143 report_fatal_error(ec.message()); 144 return ret.data(); 145} 146 147uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) { 148 return (*unwrap(SI))->getAddress(); 149} 150 151LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI, 152 LLVMSymbolIteratorRef Sym) { 153 return (*unwrap(SI))->containsSymbol(**unwrap(Sym)); 154} 155 156// Section Relocation iterators 157LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) { 158 relocation_iterator SI = (*unwrap(Section))->relocation_begin(); 159 return wrap(new relocation_iterator(SI)); 160} 161 162void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) { 163 delete unwrap(SI); 164} 165 166LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section, 167 LLVMRelocationIteratorRef SI) { 168 return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0; 169} 170 171void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) { 172 ++(*unwrap(SI)); 173} 174 175 176// SymbolRef accessors 177const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) { 178 ErrorOr<StringRef> Ret = (*unwrap(SI))->getName(); 179 if (std::error_code EC = Ret.getError()) 180 report_fatal_error(EC.message()); 181 return Ret->data(); 182} 183 184uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) { 185 ErrorOr<uint64_t> Ret = (*unwrap(SI))->getAddress(); 186 if (std::error_code EC = Ret.getError()) 187 report_fatal_error(EC.message()); 188 return *Ret; 189} 190 191uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) { 192 return (*unwrap(SI))->getCommonSize(); 193} 194 195// RelocationRef accessors 196uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { 197 return (*unwrap(RI))->getOffset(); 198} 199 200LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { 201 symbol_iterator ret = (*unwrap(RI))->getSymbol(); 202 return wrap(new symbol_iterator(ret)); 203} 204 205uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) { 206 return (*unwrap(RI))->getType(); 207} 208 209// NOTE: Caller takes ownership of returned string. 210const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) { 211 SmallVector<char, 0> ret; 212 (*unwrap(RI))->getTypeName(ret); 213 char *str = static_cast<char*>(malloc(ret.size())); 214 std::copy(ret.begin(), ret.end(), str); 215 return str; 216} 217 218// NOTE: Caller takes ownership of returned string. 219const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) { 220 return strdup(""); 221} 222 223