Object.cpp revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
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 ObjectFile *unwrap(LLVMObjectFileRef OF) {
23  return reinterpret_cast<ObjectFile*>(OF);
24}
25
26inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
27  return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
28}
29
30inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
31  return reinterpret_cast<section_iterator*>(SI);
32}
33
34inline LLVMSectionIteratorRef
35wrap(const section_iterator *SI) {
36  return reinterpret_cast<LLVMSectionIteratorRef>
37    (const_cast<section_iterator*>(SI));
38}
39
40inline symbol_iterator *unwrap(LLVMSymbolIteratorRef SI) {
41  return reinterpret_cast<symbol_iterator*>(SI);
42}
43
44inline LLVMSymbolIteratorRef
45wrap(const symbol_iterator *SI) {
46  return reinterpret_cast<LLVMSymbolIteratorRef>
47    (const_cast<symbol_iterator*>(SI));
48}
49
50inline relocation_iterator *unwrap(LLVMRelocationIteratorRef SI) {
51  return reinterpret_cast<relocation_iterator*>(SI);
52}
53
54inline LLVMRelocationIteratorRef
55wrap(const relocation_iterator *SI) {
56  return reinterpret_cast<LLVMRelocationIteratorRef>
57    (const_cast<relocation_iterator*>(SI));
58}
59
60// ObjectFile creation
61LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
62  std::unique_ptr<MemoryBuffer> Buf(unwrap(MemBuf));
63  ErrorOr<ObjectFile *> ObjOrErr(ObjectFile::createObjectFile(Buf));
64  Buf.release();
65  ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : nullptr;
66  return wrap(Obj);
67}
68
69void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
70  delete unwrap(ObjectFile);
71}
72
73// ObjectFile Section iterators
74LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) {
75  section_iterator SI = unwrap(ObjectFile)->section_begin();
76  return wrap(new section_iterator(SI));
77}
78
79void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
80  delete unwrap(SI);
81}
82
83LLVMBool LLVMIsSectionIteratorAtEnd(LLVMObjectFileRef ObjectFile,
84                                LLVMSectionIteratorRef SI) {
85  return (*unwrap(SI) == unwrap(ObjectFile)->section_end()) ? 1 : 0;
86}
87
88void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
89  ++(*unwrap(SI));
90}
91
92void LLVMMoveToContainingSection(LLVMSectionIteratorRef Sect,
93                                 LLVMSymbolIteratorRef Sym) {
94  if (std::error_code ec = (*unwrap(Sym))->getSection(*unwrap(Sect)))
95    report_fatal_error(ec.message());
96}
97
98// ObjectFile Symbol iterators
99LLVMSymbolIteratorRef LLVMGetSymbols(LLVMObjectFileRef ObjectFile) {
100  symbol_iterator SI = unwrap(ObjectFile)->symbol_begin();
101  return wrap(new symbol_iterator(SI));
102}
103
104void LLVMDisposeSymbolIterator(LLVMSymbolIteratorRef SI) {
105  delete unwrap(SI);
106}
107
108LLVMBool LLVMIsSymbolIteratorAtEnd(LLVMObjectFileRef ObjectFile,
109                                LLVMSymbolIteratorRef SI) {
110  return (*unwrap(SI) == unwrap(ObjectFile)->symbol_end()) ? 1 : 0;
111}
112
113void LLVMMoveToNextSymbol(LLVMSymbolIteratorRef SI) {
114  ++(*unwrap(SI));
115}
116
117// SectionRef accessors
118const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
119  StringRef ret;
120  if (std::error_code ec = (*unwrap(SI))->getName(ret))
121   report_fatal_error(ec.message());
122  return ret.data();
123}
124
125uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
126  uint64_t ret;
127  if (std::error_code ec = (*unwrap(SI))->getSize(ret))
128    report_fatal_error(ec.message());
129  return ret;
130}
131
132const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
133  StringRef ret;
134  if (std::error_code ec = (*unwrap(SI))->getContents(ret))
135    report_fatal_error(ec.message());
136  return ret.data();
137}
138
139uint64_t LLVMGetSectionAddress(LLVMSectionIteratorRef SI) {
140  uint64_t ret;
141  if (std::error_code ec = (*unwrap(SI))->getAddress(ret))
142    report_fatal_error(ec.message());
143  return ret;
144}
145
146LLVMBool LLVMGetSectionContainsSymbol(LLVMSectionIteratorRef SI,
147                                 LLVMSymbolIteratorRef Sym) {
148  bool ret;
149  if (std::error_code ec = (*unwrap(SI))->containsSymbol(**unwrap(Sym), ret))
150    report_fatal_error(ec.message());
151  return ret;
152}
153
154// Section Relocation iterators
155LLVMRelocationIteratorRef LLVMGetRelocations(LLVMSectionIteratorRef Section) {
156  relocation_iterator SI = (*unwrap(Section))->relocation_begin();
157  return wrap(new relocation_iterator(SI));
158}
159
160void LLVMDisposeRelocationIterator(LLVMRelocationIteratorRef SI) {
161  delete unwrap(SI);
162}
163
164LLVMBool LLVMIsRelocationIteratorAtEnd(LLVMSectionIteratorRef Section,
165                                       LLVMRelocationIteratorRef SI) {
166  return (*unwrap(SI) == (*unwrap(Section))->relocation_end()) ? 1 : 0;
167}
168
169void LLVMMoveToNextRelocation(LLVMRelocationIteratorRef SI) {
170  ++(*unwrap(SI));
171}
172
173
174// SymbolRef accessors
175const char *LLVMGetSymbolName(LLVMSymbolIteratorRef SI) {
176  StringRef ret;
177  if (std::error_code ec = (*unwrap(SI))->getName(ret))
178    report_fatal_error(ec.message());
179  return ret.data();
180}
181
182uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
183  uint64_t ret;
184  if (std::error_code ec = (*unwrap(SI))->getAddress(ret))
185    report_fatal_error(ec.message());
186  return ret;
187}
188
189uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
190  uint64_t ret;
191  if (std::error_code ec = (*unwrap(SI))->getSize(ret))
192    report_fatal_error(ec.message());
193  return ret;
194}
195
196// RelocationRef accessors
197uint64_t LLVMGetRelocationAddress(LLVMRelocationIteratorRef RI) {
198  uint64_t ret;
199  if (std::error_code ec = (*unwrap(RI))->getAddress(ret))
200    report_fatal_error(ec.message());
201  return ret;
202}
203
204uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
205  uint64_t ret;
206  if (std::error_code ec = (*unwrap(RI))->getOffset(ret))
207    report_fatal_error(ec.message());
208  return ret;
209}
210
211LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
212  symbol_iterator ret = (*unwrap(RI))->getSymbol();
213  return wrap(new symbol_iterator(ret));
214}
215
216uint64_t LLVMGetRelocationType(LLVMRelocationIteratorRef RI) {
217  uint64_t ret;
218  if (std::error_code ec = (*unwrap(RI))->getType(ret))
219    report_fatal_error(ec.message());
220  return ret;
221}
222
223// NOTE: Caller takes ownership of returned string.
224const char *LLVMGetRelocationTypeName(LLVMRelocationIteratorRef RI) {
225  SmallVector<char, 0> ret;
226  if (std::error_code ec = (*unwrap(RI))->getTypeName(ret))
227    report_fatal_error(ec.message());
228
229  char *str = static_cast<char*>(malloc(ret.size()));
230  std::copy(ret.begin(), ret.end(), str);
231  return str;
232}
233
234// NOTE: Caller takes ownership of returned string.
235const char *LLVMGetRelocationValueString(LLVMRelocationIteratorRef RI) {
236  SmallVector<char, 0> ret;
237  if (std::error_code ec = (*unwrap(RI))->getValueString(ret))
238    report_fatal_error(ec.message());
239
240  char *str = static_cast<char*>(malloc(ret.size()));
241  std::copy(ret.begin(), ret.end(), str);
242  return str;
243}
244
245