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