1221337Sdim//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
2221337Sdim//
3221337Sdim//                     The LLVM Compiler Infrastructure
4221337Sdim//
5221337Sdim// This file is distributed under the University of Illinois Open Source
6221337Sdim// License. See LICENSE.TXT for details.
7221337Sdim//
8221337Sdim//===----------------------------------------------------------------------===//
9221337Sdim//
10221337Sdim// This file defines the C bindings to the file-format-independent object
11221337Sdim// library.
12221337Sdim//
13221337Sdim//===----------------------------------------------------------------------===//
14221337Sdim
15252723Sdim#include "llvm/ADT/SmallVector.h"
16221337Sdim#include "llvm/Object/ObjectFile.h"
17221337Sdim#include "llvm-c/Object.h"
18221337Sdim
19221337Sdimusing namespace llvm;
20221337Sdimusing namespace object;
21221337Sdim
22252723Sdiminline ObjectFile *unwrap(LLVMObjectFileRef OF) {
23252723Sdim  return reinterpret_cast<ObjectFile*>(OF);
24252723Sdim}
25252723Sdim
26252723Sdiminline LLVMObjectFileRef wrap(const ObjectFile *OF) {
27252723Sdim  return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
28252723Sdim}
29252723Sdim
30252723Sdiminline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
31252723Sdim  return reinterpret_cast<section_iterator*>(SI);
32252723Sdim}
33252723Sdim
34252723Sdiminline LLVMSectionIteratorRef
35252723Sdimwrap(const section_iterator *SI) {
36252723Sdim  return reinterpret_cast<LLVMSectionIteratorRef>
37252723Sdim    (const_cast<section_iterator*>(SI));
38252723Sdim}
39252723Sdim
40252723Sdiminline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
41252723Sdim  return reinterpret_cast<symbol_iterator*>(SI);
42252723Sdim}
43252723Sdim
44252723Sdiminline LLVMSymbolIteratorRef
45252723Sdimwrap(const symbol_iterator *SI) {
46252723Sdim  return reinterpret_cast<LLVMSymbolIteratorRef>
47252723Sdim    (const_cast<symbol_iterator*>(SI));
48252723Sdim}
49252723Sdim
50252723Sdiminline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
51252723Sdim  return reinterpret_cast<relocation_iterator*>(SI);
52252723Sdim}
53252723Sdim
54252723Sdiminline LLVMRelocationIteratorRef
55252723Sdimwrap(const relocation_iterator *SI) {
56252723Sdim  return reinterpret_cast<LLVMRelocationIteratorRef>
57252723Sdim    (const_cast<relocation_iterator*>(SI));
58252723Sdim}
59252723Sdim
60235633Sdim// ObjectFile creation
61221337SdimLLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
62221337Sdim  return wrap(ObjectFile::createObjectFile(unwrap(MemBuf)));
63221337Sdim}
64221337Sdim
65221337Sdimvoid LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
66221337Sdim  delete unwrap(ObjectFile);
67221337Sdim}
68221337Sdim
69235633Sdim// ObjectFile Section iterators
70221337SdimLLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) {
71226890Sdim  section_iterator SI = unwrap(ObjectFile)->begin_sections();
72226890Sdim  return wrap(new section_iterator(SI));
73221337Sdim}
74221337Sdim
75221337Sdimvoid LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
76221337Sdim  delete unwrap(SI);
77221337Sdim}
78221337Sdim
79221337SdimLLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
80221337Sdim                                LLVMSectionIteratorRef SI) {
81221337Sdim  return (*unwrap(SI) == unwrap(ObjectFile)->end_sections()) ? 1 : 0;
82221337Sdim}
83221337Sdim
84221337Sdimvoid LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
85224145Sdim  error_code ec;
86224145Sdim  unwrap(SI)->increment(ec);
87224145Sdim  if (ec) report_fatal_error("LLVMMoveToNextSection failed: " + ec.message());
88221337Sdim}
89221337Sdim
90235633Sdimvoid LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
91235633Sdim                                 LLVMSymbolIteratorRef Sym) {
92235633Sdim  if (error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect)))
93235633Sdim    report_fatal_error(ec.message());
94235633Sdim}
95235633Sdim
96235633Sdim// ObjectFile Symbol iterators
97235633SdimLLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) {
98235633Sdim  symbol_iterator SI = unwrap(ObjectFile)->begin_symbols();
99235633Sdim  return wrap(new symbol_iterator(SI));
100235633Sdim}
101235633Sdim
102235633Sdimvoid LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
103235633Sdim  delete unwrap(SI);
104235633Sdim}
105235633Sdim
106235633SdimLLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
107235633Sdim                                LLVMSymbolIteratorRef SI) {
108235633Sdim  return (*unwrap(SI) == unwrap(ObjectFile)->end_symbols()) ? 1 : 0;
109235633Sdim}
110235633Sdim
111235633Sdimvoid LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
112235633Sdim  error_code ec;
113235633Sdim  unwrap(SI)->increment(ec);
114235633Sdim  if (ec) report_fatal_error("LLVMMoveToNextSymbol failed: " + ec.message());
115235633Sdim}
116235633Sdim
117235633Sdim// SectionRef accessors
118221337Sdimconst char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
119224145Sdim  StringRef ret;
120224145Sdim  if (error_code ec = (*unwrap(SI))->getName(ret))
121224145Sdim   report_fatal_error(ec.message());
122224145Sdim  return ret.data();
123221337Sdim}
124221337Sdim
125221337Sdimuint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
126224145Sdim  uint64_t ret;
127224145Sdim  if (error_code ec = (*unwrap(SI))->getSize(ret))
128224145Sdim    report_fatal_error(ec.message());
129224145Sdim  return ret;
130221337Sdim}
131221337Sdim
132221337Sdimconst char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
133224145Sdim  StringRef ret;
134224145Sdim  if (error_code ec = (*unwrap(SI))->getContents(ret))
135224145Sdim    report_fatal_error(ec.message());
136224145Sdim  return ret.data();
137221337Sdim}
138235633Sdim
139235633Sdimuint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
140235633Sdim  uint64_t ret;
141235633Sdim  if (error_code ec = (*unwrap(SI))->getAddress(ret))
142235633Sdim    report_fatal_error(ec.message());
143235633Sdim  return ret;
144235633Sdim}
145235633Sdim
146235633SdimLLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
147235633Sdim                                 LLVMSymbolIteratorRef Sym) {
148235633Sdim  bool ret;
149235633Sdim  if (error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret))
150235633Sdim    report_fatal_error(ec.message());
151235633Sdim  return ret;
152235633Sdim}
153235633Sdim
154235633Sdim// Section Relocation iterators
155235633SdimLLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
156235633Sdim  relocation_iterator SI = (*unwrap(Section))->begin_relocations();
157235633Sdim  return wrap(new relocation_iterator(SI));
158235633Sdim}
159235633Sdim
160235633Sdimvoid LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
161235633Sdim  delete unwrap(SI);
162235633Sdim}
163235633Sdim
164235633SdimLLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
165235633Sdim                                       LLVMRelocationIteratorRef SI) {
166235633Sdim  return (*unwrap(SI) == (*unwrap(Section))->end_relocations()) ? 1 : 0;
167235633Sdim}
168235633Sdim
169235633Sdimvoid LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
170235633Sdim  error_code ec;
171235633Sdim  unwrap(SI)->increment(ec);
172235633Sdim  if (ec) report_fatal_error("LLVMMoveToNextRelocation failed: " +
173235633Sdim                             ec.message());
174235633Sdim}
175235633Sdim
176235633Sdim
177235633Sdim// SymbolRef accessors
178235633Sdimconst char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
179235633Sdim  StringRef ret;
180235633Sdim  if (error_code ec = (*unwrap(SI))->getName(ret))
181235633Sdim    report_fatal_error(ec.message());
182235633Sdim  return ret.data();
183235633Sdim}
184235633Sdim
185235633Sdimuint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
186235633Sdim  uint64_t ret;
187235633Sdim  if (error_code ec = (*unwrap(SI))->getAddress(ret))
188235633Sdim    report_fatal_error(ec.message());
189235633Sdim  return ret;
190235633Sdim}
191235633Sdim
192235633Sdimuint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI) {
193235633Sdim  uint64_t ret;
194235633Sdim  if (error_code ec = (*unwrap(SI))->getFileOffset(ret))
195235633Sdim    report_fatal_error(ec.message());
196235633Sdim  return ret;
197235633Sdim}
198235633Sdim
199235633Sdimuint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
200235633Sdim  uint64_t ret;
201235633Sdim  if (error_code ec = (*unwrap(SI))->getSize(ret))
202235633Sdim    report_fatal_error(ec.message());
203235633Sdim  return ret;
204235633Sdim}
205235633Sdim
206235633Sdim// RelocationRef accessors
207235633Sdimuint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) {
208235633Sdim  uint64_t ret;
209235633Sdim  if (error_code ec = (*unwrap(RI))->getAddress(ret))
210235633Sdim    report_fatal_error(ec.message());
211235633Sdim  return ret;
212235633Sdim}
213235633Sdim
214235633Sdimuint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
215235633Sdim  uint64_t ret;
216235633Sdim  if (error_code ec = (*unwrap(RI))->getOffset(ret))
217235633Sdim    report_fatal_error(ec.message());
218235633Sdim  return ret;
219235633Sdim}
220235633Sdim
221235633SdimLLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
222263509Sdim  symbol_iterator ret = (*unwrap(RI))->getSymbol();
223235633Sdim  return wrap(new symbol_iterator(ret));
224235633Sdim}
225235633Sdim
226235633Sdimuint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
227235633Sdim  uint64_t ret;
228235633Sdim  if (error_code ec = (*unwrap(RI))->getType(ret))
229235633Sdim    report_fatal_error(ec.message());
230235633Sdim  return ret;
231235633Sdim}
232235633Sdim
233235633Sdim// NOTE: Caller takes ownership of returned string.
234235633Sdimconst char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
235235633Sdim  SmallVector<char, 0> ret;
236235633Sdim  if (error_code ec = (*unwrap(RI))->getTypeName(ret))
237235633Sdim    report_fatal_error(ec.message());
238235633Sdim
239235633Sdim  char *str = static_cast<char*>(malloc(ret.size()));
240235633Sdim  std::copy(ret.begin(), ret.end(), str);
241235633Sdim  return str;
242235633Sdim}
243235633Sdim
244235633Sdim// NOTE: Caller takes ownership of returned string.
245235633Sdimconst char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
246235633Sdim  SmallVector<char, 0> ret;
247235633Sdim  if (error_code ec = (*unwrap(RI))->getValueString(ret))
248235633Sdim    report_fatal_error(ec.message());
249235633Sdim
250235633Sdim  char *str = static_cast<char*>(malloc(ret.size()));
251235633Sdim  std::copy(ret.begin(), ret.end(), str);
252235633Sdim  return str;
253235633Sdim}
254235633Sdim
255