llvm.org GIT mirror llvm / 5ae0427
[llvm.py] Initial skeleton for Python LLVM bindings This contains a semi-functional skeleton for the implementation of the LLVM bindings for Python. The API for the Object.h interface is roughly designed but not implemented. MemoryBufferRef is implemented and actually appears to work! The ObjectFile unit test fails with a segmentation fault because the LLVM library isn't being properly initialized. The build system doesn't know about this code yet, so no alerts should fire. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152397 91177308-0d34-0410-b5e6-96231b3b80d8 Gregory Szorc 7 years ago
7 changed file(s) with 361 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
(New empty file)
0 #===- common.py - Python LLVM Bindings -----------------------*- python -*--===#
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 #===------------------------------------------------------------------------===#
8
9 from ctypes import cdll
10
11 import ctypes.util
12 import platform
13
14 __all__ = [
15 "find_library",
16 "get_library",
17 ]
18
19 def find_library():
20 # FIXME should probably have build system define absolute path of shared
21 # library at install time.
22 for lib in ["LLVM-3.1svn", "LLVM"]:
23 result = ctypes.util.find_library(lib)
24 if result:
25 return result
26
27 # FIXME This is a local hack to ease development.
28 return "/usr/local/llvm/lib/libLLVM-3.1svn.so"
29
30 def get_library():
31 """Obtain a reference to the llvm library."""
32 lib = find_library()
33 if not lib:
34 raise Exception("LLVM shared library not found!")
35
36 return cdll.LoadLibrary(lib)
0 #===- core.py - Python LLVM Bindings -------------------------*- python -*--===#
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 #===------------------------------------------------------------------------===#
8
9 from .common import get_library
10
11 from ctypes import POINTER
12 from ctypes import byref
13 from ctypes import c_char_p
14 from ctypes import c_void_p
15
16 __all__ = [
17 "lib",
18 "MemoryBufferRef",
19 ]
20
21 lib = get_library()
22
23 class MemoryBuffer(object):
24 """Represents an opaque memory buffer."""
25
26 def __init__(self, filename=None):
27 """Create a new memory buffer.
28
29 Currently, we support creating from the contents of a file at the
30 specified filename.
31 """
32 if filename is None:
33 raise Exception("filename argument must be defined")
34
35 memory = c_void_p(None)
36 out = c_char_p(None)
37
38 result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename,
39 byref(memory), byref(out))
40
41 if result:
42 raise Exception("Could not create memory buffer: %s" % out.value)
43
44 self._memory = memory
45
46 def __del__(self):
47 lib.LLVMDisposeMemoryBuffer(self._memory)
48
49 def from_param(self):
50 return self._memory
51
52
53 def register_library(library):
54 library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
55 POINTER(c_void_p), POINTER(c_char_p)]
56 library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
57
58 library.LLVMDisposeMemoryBuffer.argtypes = [c_void_p]
59
60 register_library(lib)
0 #===- object.py - Python Object Bindings --------------------*- python -*--===#
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 #===------------------------------------------------------------------------===#
8
9 from ctypes import c_char_p
10 from ctypes import c_uint64
11 from ctypes import c_void_p
12
13 from .common import get_library
14 from .core import MemoryBuffer
15
16 __all__ = [
17 "lib",
18 "ObjectFile",
19 "Relocation",
20 "Section",
21 "Symbol",
22 ]
23
24 class ObjectFile(object):
25 """Represents an object/binary file."""
26
27 def __init__(self, filename=None, contents=None):
28 """Construct an instance from a filename or binary data.
29
30 filename must be a path to a file that can be opened with open().
31 contents can be either a native Python buffer type (like str) or a
32 llvm.core.MemoryBuffer instance.
33 """
34 if contents:
35 assert isinstance(contents, MemoryBuffer)
36
37 if filename is not None:
38 contents = MemoryBuffer(filename=filename)
39
40 self._memory = contents
41 self._obj = lib.LLVMCreateObjectFile(contents)
42
43 def __del__(self):
44 lib.LLVMDisposeObjectFile(self._obj)
45
46 def get_sections(self):
47 """Obtain the sections in this object file.
48
49 This is an iterator for llvm.object.Section instances.
50 """
51 pass
52
53 def get_symbols(self):
54 """Obtain the symbols in this object file.
55
56 This is an iterator for llvm.object.Symbol instances.
57 """
58
59 class Section(object):
60 """Represents a section in an object file."""
61
62 def __init__(self, obj=None):
63 """Construct a new section instance.
64
65 Section instances can currently only be created from an ObjectFile
66 instance. Therefore, this constructor should not be used outside of
67 this module.
68 """
69 pass
70
71 def __del__(self):
72 pass
73
74 @property
75 def name(self):
76 pass
77
78 @property
79 def size(self):
80 pass
81
82 @property
83 def contents(self):
84 pass
85
86 @property
87 def address(self):
88 pass
89
90 # TODO consider exposing more Pythonic interface, like __contains__
91 def has_symbol(self, symbol):
92 pass
93
94 def get_relocations(self):
95 pass
96
97 class Symbol(object):
98 def __init__(self):
99 pass
100
101 @property
102 def name(self):
103 pass
104
105 @property
106 def address(self):
107 pass
108
109 @property
110 def file_offset(self):
111 pass
112
113 @property
114 def size(self):
115 pass
116
117 class Relocation(object):
118 def __init__(self):
119 pass
120
121 @property
122 def address(self):
123 pass
124
125 @property
126 def offset(self):
127 pass
128
129 @property
130 def symbol(self):
131 pass
132
133 @property
134 def type(self):
135 pass
136
137 @property
138 def type_name(self):
139 pass
140
141 @property
142 def value_string(self):
143 pass
144
145 ObjectFileRef = c_void_p
146 SectionIteratorRef = c_void_p
147 SymbolIteratorRef = c_void_p
148 RelocationIteratorRef = c_void_p
149
150 def register_library(library):
151 """Register function prototypes with LLVM library instance."""
152
153 # Object.h functions
154 library.LLVMCreateObjectFile.argtypes = [MemoryBuffer]
155 library.LLVMCreateObjectFile.restype = ObjectFileRef
156
157 library.LLVMDisposeObjectFile.argtypes = [ObjectFileRef]
158
159 library.LLVMGetSections.argtypes = [ObjectFileRef]
160 library.LLVMGetSections.restype = SectionIteratorRef
161
162 library.LLVMDisposeSectionIterator.argtypes = [SectionIteratorRef]
163
164 library.LLVMIsSectionIteratorAtEnd.argtypes = [ObjectFileRef,
165 SectionIteratorRef]
166 library.LLVMIsSectionIteratorAtEnd.restype = bool
167
168 library.LLVMMoveToNextSection.argtypes = [SectionIteratorRef]
169
170 library.LLVMMoveToContainingSection.argtypes = [SectionIteratorRef,
171 SymbolIteratorRef]
172
173 library.LLVMGetSymbols.argtypes = [ObjectFileRef]
174 library.LLVMGetSymbols.restype = SymbolIteratorRef
175
176 library.LLVMDisposeSymbolIterator.argtypes = [SymbolIteratorRef]
177
178 library.LLVMIsSymbolIteratorAtEnd.argtypes = [ObjectFileRef,
179 SymbolIteratorRef]
180 library.LLVMIsSymbolIteratorAtEnd.restype = bool
181
182 library.LLVMMoveToNextSymbol.argtypes = [SymbolIteratorRef]
183
184 library.LLVMGetSectionName.argtypes = [SectionIteratorRef]
185 library.LLVMGetSectionName.restype = c_char_p
186
187 library.LLVMGetSectionSize.argtypes = [SectionIteratorRef]
188 library.LLVMGetSectionSize.restype = c_uint64
189
190 library.LLVMGetSectionContents.argtypes = [SectionIteratorRef]
191 library.LLVMGetSectionContents.restype = c_char_p
192
193 library.LLVMGetSectionAddress.argtypes = [SectionIteratorRef]
194 library.LLVMGetSectionAddress.restype = c_uint64
195
196 library.LLVMGetSectionContainsSymbol.argtypes = [SectionIteratorRef,
197 SymbolIteratorRef]
198 library.LLVMGetSectionContainsSymbol.restype = bool
199
200 library.LLVMGetRelocations.argtypes = [SectionIteratorRef]
201 library.LLVMGetRelocations.restype = RelocationIteratorRef
202
203 library.LLVMDisposeRelocationIterator.argtypes = [RelocationIteratorRef]
204
205 library.LLVMIsRelocationIteratorAtEnd.argtypes = [SectionIteratorRef,
206 RelocationIteratorRef]
207 library.LLVMIsRelocationIteratorAtEnd.restype = bool
208
209 library.LLVMMoveToNextRelocation.argtypes = [RelocationIteratorRef]
210
211 library.LLVMGetSymbolName.argtypes = [SymbolIteratorRef]
212 library.LLVMGetSymbolName.restype = c_char_p
213
214 library.LLVMGetSymbolAddress.argtypes = [SymbolIteratorRef]
215 library.LLVMGetSymbolAddress.restype = c_uint64
216
217 library.LLVMGetSymbolFileOffset.argtypes = [SymbolIteratorRef]
218 library.LLVMGetSymbolFileOffset.restype = c_uint64
219
220 library.LLVMGetSymbolSize.argtypes = [SymbolIteratorRef]
221 library.LLVMGetSymbolSize.restype = c_uint64
222
223 library.LLVMGetRelocationAddress.argtypes = [SymbolIteratorRef]
224 library.LLVMGetRelocationAddress.restype = c_uint64
225
226 library.LLVMGetRelocationOffset.argtypes = [RelocationIteratorRef]
227 library.LLVMGetRelocationOffset.restype = c_uint64
228
229 library.LLVMGetRelocationSymbol.argtypes = [RelocationIteratorRef]
230 library.LLVMGetRelocationSymbol.restype = SymbolIteratorRef
231
232 library.LLVMGetRelocationType.argtypes = [RelocationIteratorRef]
233 library.LLVMGetRelocationType.restype = c_uint64
234
235 library.LLVMGetRelocationTypeName.argtypes = [RelocationIteratorRef]
236 library.LLVMGetRelocationTypeName.restype = c_char_p
237
238 library.LLVMGetRelocationValueString.argtypes = [RelocationIteratorRef]
239 library.LLVMGetRelocationValueString.restype = c_char_p
240
241 lib = get_library()
242 register_library(lib)
0 from llvm.common import find_library
1 from llvm.core import MemoryBuffer
2
3 import unittest
4
5 class TestCore(unittest.TestCase):
6 def test_memory_buffer_create_from_file(self):
7 source = find_library()
8 self.assertIsNotNone(source)
9
10 mb = MemoryBuffer(filename=source)
0 from llvm.common import find_library
1 from llvm.object import ObjectFile
2
3 import unittest
4
5 class TestObjectFile(unittest.TestCase):
6 def test_create_from_file(self):
7 source = find_library()
8 of = ObjectFile(filename=source)