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