10b57cec5SDimitry Andric //===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the C bindings to the file-format-independent object
100b57cec5SDimitry Andric // library.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm-c/Object.h"
150b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
160b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
170b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
180b57cec5SDimitry Andric #include "llvm/Object/MachOUniversal.h"
1904eeddc0SDimitry Andric #include "llvm/Support/MemAlloc.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric using namespace object;
230b57cec5SDimitry Andric 
unwrap(LLVMObjectFileRef OF)240b57cec5SDimitry Andric inline OwningBinary<ObjectFile> *unwrap(LLVMObjectFileRef OF) {
250b57cec5SDimitry Andric   return reinterpret_cast<OwningBinary<ObjectFile> *>(OF);
260b57cec5SDimitry Andric }
270b57cec5SDimitry Andric 
wrap(const OwningBinary<ObjectFile> * OF)280b57cec5SDimitry Andric inline LLVMObjectFileRef wrap(const OwningBinary<ObjectFile> *OF) {
290b57cec5SDimitry Andric   return reinterpret_cast<LLVMObjectFileRef>(
300b57cec5SDimitry Andric       const_cast<OwningBinary<ObjectFile> *>(OF));
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric 
unwrap(LLVMSectionIteratorRef SI)330b57cec5SDimitry Andric inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
340b57cec5SDimitry Andric   return reinterpret_cast<section_iterator*>(SI);
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric inline LLVMSectionIteratorRef
wrap(const section_iterator * SI)380b57cec5SDimitry Andric wrap(const section_iterator *SI) {
390b57cec5SDimitry Andric   return reinterpret_cast<LLVMSectionIteratorRef>
400b57cec5SDimitry Andric     (const_cast<section_iterator*>(SI));
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric 
unwrap(LLVMSymbolIteratorRef SI)430b57cec5SDimitry Andric inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
440b57cec5SDimitry Andric   return reinterpret_cast<symbol_iterator*>(SI);
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric inline LLVMSymbolIteratorRef
wrap(const symbol_iterator * SI)480b57cec5SDimitry Andric wrap(const symbol_iterator *SI) {
490b57cec5SDimitry Andric   return reinterpret_cast<LLVMSymbolIteratorRef>
500b57cec5SDimitry Andric     (const_cast<symbol_iterator*>(SI));
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
unwrap(LLVMRelocationIteratorRef SI)530b57cec5SDimitry Andric inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
540b57cec5SDimitry Andric   return reinterpret_cast<relocation_iterator*>(SI);
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric inline LLVMRelocationIteratorRef
wrap(const relocation_iterator * SI)580b57cec5SDimitry Andric wrap(const relocation_iterator *SI) {
590b57cec5SDimitry Andric   return reinterpret_cast<LLVMRelocationIteratorRef>
600b57cec5SDimitry Andric     (const_cast<relocation_iterator*>(SI));
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric /*--.. Operations on binary files ..........................................--*/
640b57cec5SDimitry Andric 
LLVMCreateBinary(LLVMMemoryBufferRef MemBuf,LLVMContextRef Context,char ** ErrorMessage)650b57cec5SDimitry Andric LLVMBinaryRef LLVMCreateBinary(LLVMMemoryBufferRef MemBuf,
660b57cec5SDimitry Andric                                LLVMContextRef Context,
670b57cec5SDimitry Andric                                char **ErrorMessage) {
680b57cec5SDimitry Andric   auto maybeContext = Context ? unwrap(Context) : nullptr;
690b57cec5SDimitry Andric   Expected<std::unique_ptr<Binary>> ObjOrErr(
700b57cec5SDimitry Andric       createBinary(unwrap(MemBuf)->getMemBufferRef(), maybeContext));
710b57cec5SDimitry Andric   if (!ObjOrErr) {
720b57cec5SDimitry Andric     *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
730b57cec5SDimitry Andric     return nullptr;
740b57cec5SDimitry Andric   }
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   return wrap(ObjOrErr.get().release());
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR)790b57cec5SDimitry Andric LLVMMemoryBufferRef LLVMBinaryCopyMemoryBuffer(LLVMBinaryRef BR) {
800b57cec5SDimitry Andric   auto Buf = unwrap(BR)->getMemoryBufferRef();
810b57cec5SDimitry Andric   return wrap(llvm::MemoryBuffer::getMemBuffer(
820b57cec5SDimitry Andric                 Buf.getBuffer(), Buf.getBufferIdentifier(),
830b57cec5SDimitry Andric                 /*RequiresNullTerminator*/false).release());
840b57cec5SDimitry Andric }
850b57cec5SDimitry Andric 
LLVMDisposeBinary(LLVMBinaryRef BR)860b57cec5SDimitry Andric void LLVMDisposeBinary(LLVMBinaryRef BR) {
870b57cec5SDimitry Andric   delete unwrap(BR);
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric 
LLVMBinaryGetType(LLVMBinaryRef BR)900b57cec5SDimitry Andric LLVMBinaryType LLVMBinaryGetType(LLVMBinaryRef BR) {
910b57cec5SDimitry Andric   class BinaryTypeMapper final : public Binary {
920b57cec5SDimitry Andric   public:
930b57cec5SDimitry Andric     static LLVMBinaryType mapBinaryTypeToLLVMBinaryType(unsigned Kind) {
940b57cec5SDimitry Andric       switch (Kind) {
950b57cec5SDimitry Andric       case ID_Archive:
960b57cec5SDimitry Andric         return LLVMBinaryTypeArchive;
970b57cec5SDimitry Andric       case ID_MachOUniversalBinary:
980b57cec5SDimitry Andric         return LLVMBinaryTypeMachOUniversalBinary;
990b57cec5SDimitry Andric       case ID_COFFImportFile:
1000b57cec5SDimitry Andric         return LLVMBinaryTypeCOFFImportFile;
1010b57cec5SDimitry Andric       case ID_IR:
1020b57cec5SDimitry Andric         return LLVMBinaryTypeIR;
1030b57cec5SDimitry Andric       case ID_WinRes:
1040b57cec5SDimitry Andric         return LLVMBinaryTypeWinRes;
1050b57cec5SDimitry Andric       case ID_COFF:
1060b57cec5SDimitry Andric         return LLVMBinaryTypeCOFF;
1070b57cec5SDimitry Andric       case ID_ELF32L:
1080b57cec5SDimitry Andric         return LLVMBinaryTypeELF32L;
1090b57cec5SDimitry Andric       case ID_ELF32B:
1100b57cec5SDimitry Andric         return LLVMBinaryTypeELF32B;
1110b57cec5SDimitry Andric       case ID_ELF64L:
1120b57cec5SDimitry Andric         return LLVMBinaryTypeELF64L;
1130b57cec5SDimitry Andric       case ID_ELF64B:
1140b57cec5SDimitry Andric         return LLVMBinaryTypeELF64B;
1150b57cec5SDimitry Andric       case ID_MachO32L:
1160b57cec5SDimitry Andric         return LLVMBinaryTypeMachO32L;
1170b57cec5SDimitry Andric       case ID_MachO32B:
1180b57cec5SDimitry Andric         return LLVMBinaryTypeMachO32B;
1190b57cec5SDimitry Andric       case ID_MachO64L:
1200b57cec5SDimitry Andric         return LLVMBinaryTypeMachO64L;
1210b57cec5SDimitry Andric       case ID_MachO64B:
1220b57cec5SDimitry Andric         return LLVMBinaryTypeMachO64B;
12381ad6265SDimitry Andric       case ID_Offload:
12481ad6265SDimitry Andric         return LLVMBinaryTypeOffload;
1250b57cec5SDimitry Andric       case ID_Wasm:
1260b57cec5SDimitry Andric         return LLVMBinaryTypeWasm;
1270b57cec5SDimitry Andric       case ID_StartObjects:
1280b57cec5SDimitry Andric       case ID_EndObjects:
1290b57cec5SDimitry Andric         llvm_unreachable("Marker types are not valid binary kinds!");
1300b57cec5SDimitry Andric       default:
1310b57cec5SDimitry Andric         llvm_unreachable("Unknown binary kind!");
1320b57cec5SDimitry Andric       }
1330b57cec5SDimitry Andric     }
1340b57cec5SDimitry Andric   };
1350b57cec5SDimitry Andric   return BinaryTypeMapper::mapBinaryTypeToLLVMBinaryType(unwrap(BR)->getType());
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR,const char * Arch,size_t ArchLen,char ** ErrorMessage)1380b57cec5SDimitry Andric LLVMBinaryRef LLVMMachOUniversalBinaryCopyObjectForArch(LLVMBinaryRef BR,
1390b57cec5SDimitry Andric                                                         const char *Arch,
1400b57cec5SDimitry Andric                                                         size_t ArchLen,
1410b57cec5SDimitry Andric                                                         char **ErrorMessage) {
1420b57cec5SDimitry Andric   auto universal = cast<MachOUniversalBinary>(unwrap(BR));
1430b57cec5SDimitry Andric   Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
1448bcb0991SDimitry Andric       universal->getMachOObjectForArch({Arch, ArchLen}));
1450b57cec5SDimitry Andric   if (!ObjOrErr) {
1460b57cec5SDimitry Andric     *ErrorMessage = strdup(toString(ObjOrErr.takeError()).c_str());
1470b57cec5SDimitry Andric     return nullptr;
1480b57cec5SDimitry Andric   }
1490b57cec5SDimitry Andric   return wrap(ObjOrErr.get().release());
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR)1520b57cec5SDimitry Andric LLVMSectionIteratorRef LLVMObjectFileCopySectionIterator(LLVMBinaryRef BR) {
1530b57cec5SDimitry Andric   auto OF = cast<ObjectFile>(unwrap(BR));
1540b57cec5SDimitry Andric   auto sections = OF->sections();
1550b57cec5SDimitry Andric   if (sections.begin() == sections.end())
1560b57cec5SDimitry Andric     return nullptr;
1570b57cec5SDimitry Andric   return wrap(new section_iterator(sections.begin()));
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR,LLVMSectionIteratorRef SI)1600b57cec5SDimitry Andric LLVMBool LLVMObjectFileIsSectionIteratorAtEnd(LLVMBinaryRef BR,
1610b57cec5SDimitry Andric                                               LLVMSectionIteratorRef SI) {
1620b57cec5SDimitry Andric   auto OF = cast<ObjectFile>(unwrap(BR));
1630b57cec5SDimitry Andric   return (*unwrap(SI) == OF->section_end()) ? 1 : 0;
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric 
LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR)1660b57cec5SDimitry Andric LLVMSymbolIteratorRef LLVMObjectFileCopySymbolIterator(LLVMBinaryRef BR) {
1670b57cec5SDimitry Andric   auto OF = cast<ObjectFile>(unwrap(BR));
1680b57cec5SDimitry Andric   auto symbols = OF->symbols();
1690b57cec5SDimitry Andric   if (symbols.begin() == symbols.end())
1700b57cec5SDimitry Andric     return nullptr;
1710b57cec5SDimitry Andric   return wrap(new symbol_iterator(symbols.begin()));
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR,LLVMSymbolIteratorRef SI)1740b57cec5SDimitry Andric LLVMBool LLVMObjectFileIsSymbolIteratorAtEnd(LLVMBinaryRef BR,
1750b57cec5SDimitry Andric                                              LLVMSymbolIteratorRef SI) {
1760b57cec5SDimitry Andric   auto OF = cast<ObjectFile>(unwrap(BR));
1770b57cec5SDimitry Andric   return (*unwrap(SI) == OF->symbol_end()) ? 1 : 0;
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric // ObjectFile creation
LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf)1810b57cec5SDimitry Andric LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
1820b57cec5SDimitry Andric   std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
1830b57cec5SDimitry Andric   Expected<std::unique_ptr<ObjectFile>> ObjOrErr(
1840b57cec5SDimitry Andric       ObjectFile::createObjectFile(Buf->getMemBufferRef()));
1850b57cec5SDimitry Andric   std::unique_ptr<ObjectFile> Obj;
1860b57cec5SDimitry Andric   if (!ObjOrErr) {
1870b57cec5SDimitry Andric     // TODO: Actually report errors helpfully.
1880b57cec5SDimitry Andric     consumeError(ObjOrErr.takeError());
1890b57cec5SDimitry Andric     return nullptr;
1900b57cec5SDimitry Andric   }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   auto *Ret = new OwningBinary<ObjectFile>(std::move(ObjOrErr.get()), std::move(Buf));
1930b57cec5SDimitry Andric   return wrap(Ret);
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile)1960b57cec5SDimitry Andric void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
1970b57cec5SDimitry Andric   delete unwrap(ObjectFile);
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric // ObjectFile Section iterators
LLVMGetSections(LLVMObjectFileRef OF)2010b57cec5SDimitry Andric LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef OF) {
2020b57cec5SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
2030b57cec5SDimitry Andric   section_iterator SI = OB->getBinary()->section_begin();
2040b57cec5SDimitry Andric   return wrap(new section_iterator(SI));
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI)2070b57cec5SDimitry Andric void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
2080b57cec5SDimitry Andric   delete unwrap(SI);
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric 
LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,LLVMSectionIteratorRef SI)2110b57cec5SDimitry Andric LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef OF,
2120b57cec5SDimitry Andric                                     LLVMSectionIteratorRef SI) {
2130b57cec5SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
2140b57cec5SDimitry Andric   return (*unwrap(SI) == OB->getBinary()->section_end()) ? 1 : 0;
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric 
LLVMMoveToNextSection(LLVMSectionIteratorRef SI)2170b57cec5SDimitry Andric void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
2180b57cec5SDimitry Andric   ++(*unwrap(SI));
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric 
LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,LLVMSymbolIteratorRef Sym)2210b57cec5SDimitry Andric void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
2220b57cec5SDimitry Andric                                  LLVMSymbolIteratorRef Sym) {
2230b57cec5SDimitry Andric   Expected<section_iterator> SecOrErr = (*unwrap(Sym))->getSection();
2240b57cec5SDimitry Andric   if (!SecOrErr) {
2250b57cec5SDimitry Andric    std::string Buf;
2260b57cec5SDimitry Andric    raw_string_ostream OS(Buf);
2270b57cec5SDimitry Andric    logAllUnhandledErrors(SecOrErr.takeError(), OS);
228349cc55cSDimitry Andric    report_fatal_error(Twine(OS.str()));
2290b57cec5SDimitry Andric   }
2300b57cec5SDimitry Andric   *unwrap(Sect) = *SecOrErr;
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric // ObjectFile Symbol iterators
LLVMGetSymbols(LLVMObjectFileRef OF)2340b57cec5SDimitry Andric LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef OF) {
2350b57cec5SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
2360b57cec5SDimitry Andric   symbol_iterator SI = OB->getBinary()->symbol_begin();
2370b57cec5SDimitry Andric   return wrap(new symbol_iterator(SI));
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric 
LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI)2400b57cec5SDimitry Andric void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
2410b57cec5SDimitry Andric   delete unwrap(SI);
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric 
LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,LLVMSymbolIteratorRef SI)2440b57cec5SDimitry Andric LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef OF,
2450b57cec5SDimitry Andric                                    LLVMSymbolIteratorRef SI) {
2460b57cec5SDimitry Andric   OwningBinary<ObjectFile> *OB = unwrap(OF);
2470b57cec5SDimitry Andric   return (*unwrap(SI) == OB->getBinary()->symbol_end()) ? 1 : 0;
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric 
LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI)2500b57cec5SDimitry Andric void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
2510b57cec5SDimitry Andric   ++(*unwrap(SI));
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric // SectionRef accessors
LLVMGetSectionName(LLVMSectionIteratorRef SI)2550b57cec5SDimitry Andric const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
2568bcb0991SDimitry Andric   auto NameOrErr = (*unwrap(SI))->getName();
2578bcb0991SDimitry Andric   if (!NameOrErr)
2588bcb0991SDimitry Andric     report_fatal_error(NameOrErr.takeError());
2598bcb0991SDimitry Andric   return NameOrErr->data();
2600b57cec5SDimitry Andric }
2610b57cec5SDimitry Andric 
LLVMGetSectionSize(LLVMSectionIteratorRef SI)2620b57cec5SDimitry Andric uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
2630b57cec5SDimitry Andric   return (*unwrap(SI))->getSize();
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
LLVMGetSectionContents(LLVMSectionIteratorRef SI)2660b57cec5SDimitry Andric const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
2670b57cec5SDimitry Andric   if (Expected<StringRef> E = (*unwrap(SI))->getContents())
2680b57cec5SDimitry Andric     return E->data();
2690b57cec5SDimitry Andric   else
2700b57cec5SDimitry Andric     report_fatal_error(E.takeError());
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric 
LLVMGetSectionAddress(LLVMSectionIteratorRef SI)2730b57cec5SDimitry Andric uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
2740b57cec5SDimitry Andric   return (*unwrap(SI))->getAddress();
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric 
LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,LLVMSymbolIteratorRef Sym)2770b57cec5SDimitry Andric LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
2780b57cec5SDimitry Andric                                  LLVMSymbolIteratorRef Sym) {
2790b57cec5SDimitry Andric   return (*unwrap(SI))->containsSymbol(**unwrap(Sym));
2800b57cec5SDimitry Andric }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric // Section Relocation iterators
LLVMGetRelocations(LLVMSectionIteratorRef Section)2830b57cec5SDimitry Andric LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
2840b57cec5SDimitry Andric   relocation_iterator SI = (*unwrap(Section))->relocation_begin();
2850b57cec5SDimitry Andric   return wrap(new relocation_iterator(SI));
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI)2880b57cec5SDimitry Andric void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
2890b57cec5SDimitry Andric   delete unwrap(SI);
2900b57cec5SDimitry Andric }
2910b57cec5SDimitry Andric 
LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,LLVMRelocationIteratorRef SI)2920b57cec5SDimitry Andric LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
2930b57cec5SDimitry Andric                                        LLVMRelocationIteratorRef SI) {
2940b57cec5SDimitry Andric   return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric 
LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI)2970b57cec5SDimitry Andric void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
2980b57cec5SDimitry Andric   ++(*unwrap(SI));
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric // SymbolRef accessors
LLVMGetSymbolName(LLVMSymbolIteratorRef SI)3030b57cec5SDimitry Andric const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
3040b57cec5SDimitry Andric   Expected<StringRef> Ret = (*unwrap(SI))->getName();
3050b57cec5SDimitry Andric   if (!Ret) {
3060b57cec5SDimitry Andric     std::string Buf;
3070b57cec5SDimitry Andric     raw_string_ostream OS(Buf);
3080b57cec5SDimitry Andric     logAllUnhandledErrors(Ret.takeError(), OS);
309349cc55cSDimitry Andric     report_fatal_error(Twine(OS.str()));
3100b57cec5SDimitry Andric   }
3110b57cec5SDimitry Andric   return Ret->data();
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI)3140b57cec5SDimitry Andric uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
3150b57cec5SDimitry Andric   Expected<uint64_t> Ret = (*unwrap(SI))->getAddress();
3160b57cec5SDimitry Andric   if (!Ret) {
3170b57cec5SDimitry Andric     std::string Buf;
3180b57cec5SDimitry Andric     raw_string_ostream OS(Buf);
3190b57cec5SDimitry Andric     logAllUnhandledErrors(Ret.takeError(), OS);
320349cc55cSDimitry Andric     report_fatal_error(Twine(OS.str()));
3210b57cec5SDimitry Andric   }
3220b57cec5SDimitry Andric   return *Ret;
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric 
LLVMGetSymbolSize(LLVMSymbolIteratorRef SI)3250b57cec5SDimitry Andric uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
3260b57cec5SDimitry Andric   return (*unwrap(SI))->getCommonSize();
3270b57cec5SDimitry Andric }
3280b57cec5SDimitry Andric 
3290b57cec5SDimitry Andric // RelocationRef accessors
LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI)3300b57cec5SDimitry Andric uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
3310b57cec5SDimitry Andric   return (*unwrap(RI))->getOffset();
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric 
LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI)3340b57cec5SDimitry Andric LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
3350b57cec5SDimitry Andric   symbol_iterator ret = (*unwrap(RI))->getSymbol();
3360b57cec5SDimitry Andric   return wrap(new symbol_iterator(ret));
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric 
LLVMGetRelocationType(LLVMRelocationIteratorRef RI)3390b57cec5SDimitry Andric uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
3400b57cec5SDimitry Andric   return (*unwrap(RI))->getType();
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric // NOTE: Caller takes ownership of returned string.
LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI)3440b57cec5SDimitry Andric const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
3450b57cec5SDimitry Andric   SmallVector<char, 0> ret;
3460b57cec5SDimitry Andric   (*unwrap(RI))->getTypeName(ret);
3470b57cec5SDimitry Andric   char *str = static_cast<char*>(safe_malloc(ret.size()));
3480b57cec5SDimitry Andric   llvm::copy(ret, str);
3490b57cec5SDimitry Andric   return str;
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric // NOTE: Caller takes ownership of returned string.
LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI)3530b57cec5SDimitry Andric const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
3540b57cec5SDimitry Andric   return strdup("");
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric 
357