xref: /aosp_15_r20/external/llvm/bindings/python/llvm/object.py (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker#===- object.py - Python Object Bindings --------------------*- python -*--===#
2*9880d681SAndroid Build Coastguard Worker#
3*9880d681SAndroid Build Coastguard Worker#                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker#
5*9880d681SAndroid Build Coastguard Worker# This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker# License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker#
8*9880d681SAndroid Build Coastguard Worker#===------------------------------------------------------------------------===#
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Workerr"""
11*9880d681SAndroid Build Coastguard WorkerObject File Interface
12*9880d681SAndroid Build Coastguard Worker=====================
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard WorkerThis module provides an interface for reading information from object files
15*9880d681SAndroid Build Coastguard Worker(e.g. binary executables and libraries).
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard WorkerUsing this module, you can obtain information about an object file's sections,
18*9880d681SAndroid Build Coastguard Workersymbols, and relocations. These are represented by the classes ObjectFile,
19*9880d681SAndroid Build Coastguard WorkerSection, Symbol, and Relocation, respectively.
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard WorkerUsage
22*9880d681SAndroid Build Coastguard Worker-----
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard WorkerThe only way to use this module is to start by creating an ObjectFile. You can
25*9880d681SAndroid Build Coastguard Workercreate an ObjectFile by loading a file (specified by its path) or by creating a
26*9880d681SAndroid Build Coastguard Workerllvm.core.MemoryBuffer and loading that.
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard WorkerOnce you have an object file, you can inspect its sections and symbols directly
29*9880d681SAndroid Build Coastguard Workerby calling get_sections() and get_symbols() respectively. To inspect
30*9880d681SAndroid Build Coastguard Workerrelocations, call get_relocations() on a Section instance.
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard WorkerIterator Interface
33*9880d681SAndroid Build Coastguard Worker------------------
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard WorkerThe LLVM bindings expose iteration over sections, symbols, and relocations in a
36*9880d681SAndroid Build Coastguard Workerway that only allows one instance to be operated on at a single time. This is
37*9880d681SAndroid Build Coastguard Workerslightly annoying from a Python perspective, as it isn't very Pythonic to have
38*9880d681SAndroid Build Coastguard Workerobjects that "expire" but are still active from a dynamic language.
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard WorkerTo aid working around this limitation, each Section, Symbol, and Relocation
41*9880d681SAndroid Build Coastguard Workerinstance caches its properties after first access. So, if the underlying
42*9880d681SAndroid Build Coastguard Workeriterator is advanced, the properties can still be obtained provided they have
43*9880d681SAndroid Build Coastguard Workeralready been retrieved.
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard WorkerIn addition, we also provide a "cache" method on each class to cache all
46*9880d681SAndroid Build Coastguard Workeravailable data. You can call this on each obtained instance. Or, you can pass
47*9880d681SAndroid Build Coastguard Workercache=True to the appropriate get_XXX() method to have this done for you.
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard WorkerHere are some examples on how to perform iteration:
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker    obj = ObjectFile(filename='/bin/ls')
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker    # This is OK. Each Section is only accessed inside its own iteration slot.
54*9880d681SAndroid Build Coastguard Worker    section_names = []
55*9880d681SAndroid Build Coastguard Worker    for section in obj.get_sections():
56*9880d681SAndroid Build Coastguard Worker        section_names.append(section.name)
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker    # This is NOT OK. You perform a lookup after the object has expired.
59*9880d681SAndroid Build Coastguard Worker    symbols = list(obj.get_symbols())
60*9880d681SAndroid Build Coastguard Worker    for symbol in symbols:
61*9880d681SAndroid Build Coastguard Worker        print symbol.name # This raises because the object has expired.
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker    # In this example, we mix a working and failing scenario.
64*9880d681SAndroid Build Coastguard Worker    symbols = []
65*9880d681SAndroid Build Coastguard Worker    for symbol in obj.get_symbols():
66*9880d681SAndroid Build Coastguard Worker        symbols.append(symbol)
67*9880d681SAndroid Build Coastguard Worker        print symbol.name
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker    for symbol in symbols:
70*9880d681SAndroid Build Coastguard Worker        print symbol.name # OK
71*9880d681SAndroid Build Coastguard Worker        print symbol.address # NOT OK. We didn't look up this property before.
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker    # Cache everything up front.
74*9880d681SAndroid Build Coastguard Worker    symbols = list(obj.get_symbols(cache=True))
75*9880d681SAndroid Build Coastguard Worker    for symbol in symbols:
76*9880d681SAndroid Build Coastguard Worker        print symbol.name # OK
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker"""
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Workerfrom ctypes import c_char_p
81*9880d681SAndroid Build Coastguard Workerfrom ctypes import c_char
82*9880d681SAndroid Build Coastguard Workerfrom ctypes import POINTER
83*9880d681SAndroid Build Coastguard Workerfrom ctypes import c_uint64
84*9880d681SAndroid Build Coastguard Workerfrom ctypes import string_at
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Workerfrom .common import CachedProperty
87*9880d681SAndroid Build Coastguard Workerfrom .common import LLVMObject
88*9880d681SAndroid Build Coastguard Workerfrom .common import c_object_p
89*9880d681SAndroid Build Coastguard Workerfrom .common import get_library
90*9880d681SAndroid Build Coastguard Workerfrom .core import MemoryBuffer
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker__all__ = [
93*9880d681SAndroid Build Coastguard Worker    "lib",
94*9880d681SAndroid Build Coastguard Worker    "ObjectFile",
95*9880d681SAndroid Build Coastguard Worker    "Relocation",
96*9880d681SAndroid Build Coastguard Worker    "Section",
97*9880d681SAndroid Build Coastguard Worker    "Symbol",
98*9880d681SAndroid Build Coastguard Worker]
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Workerclass ObjectFile(LLVMObject):
101*9880d681SAndroid Build Coastguard Worker    """Represents an object/binary file."""
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker    def __init__(self, filename=None, contents=None):
104*9880d681SAndroid Build Coastguard Worker        """Construct an instance from a filename or binary data.
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker        filename must be a path to a file that can be opened with open().
107*9880d681SAndroid Build Coastguard Worker        contents can be either a native Python buffer type (like str) or a
108*9880d681SAndroid Build Coastguard Worker        llvm.core.MemoryBuffer instance.
109*9880d681SAndroid Build Coastguard Worker        """
110*9880d681SAndroid Build Coastguard Worker        if contents:
111*9880d681SAndroid Build Coastguard Worker            assert isinstance(contents, MemoryBuffer)
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker        if filename is not None:
114*9880d681SAndroid Build Coastguard Worker            contents = MemoryBuffer(filename=filename)
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker        if contents is None:
117*9880d681SAndroid Build Coastguard Worker            raise Exception('No input found.')
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker        ptr = lib.LLVMCreateObjectFile(contents)
120*9880d681SAndroid Build Coastguard Worker        LLVMObject.__init__(self, ptr, disposer=lib.LLVMDisposeObjectFile)
121*9880d681SAndroid Build Coastguard Worker        self.take_ownership(contents)
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker    def get_sections(self, cache=False):
124*9880d681SAndroid Build Coastguard Worker        """Obtain the sections in this object file.
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker        This is a generator for llvm.object.Section instances.
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker        Sections are exposed as limited-use objects. See the module's
129*9880d681SAndroid Build Coastguard Worker        documentation on iterators for more.
130*9880d681SAndroid Build Coastguard Worker        """
131*9880d681SAndroid Build Coastguard Worker        sections = lib.LLVMGetSections(self)
132*9880d681SAndroid Build Coastguard Worker        last = None
133*9880d681SAndroid Build Coastguard Worker        while True:
134*9880d681SAndroid Build Coastguard Worker            if lib.LLVMIsSectionIteratorAtEnd(self, sections):
135*9880d681SAndroid Build Coastguard Worker                break
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker            last = Section(sections)
138*9880d681SAndroid Build Coastguard Worker            if cache:
139*9880d681SAndroid Build Coastguard Worker                last.cache()
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker            yield last
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker            lib.LLVMMoveToNextSection(sections)
144*9880d681SAndroid Build Coastguard Worker            last.expire()
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker        if last is not None:
147*9880d681SAndroid Build Coastguard Worker            last.expire()
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker        lib.LLVMDisposeSectionIterator(sections)
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker    def get_symbols(self, cache=False):
152*9880d681SAndroid Build Coastguard Worker        """Obtain the symbols in this object file.
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker        This is a generator for llvm.object.Symbol instances.
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker        Each Symbol instance is a limited-use object. See this module's
157*9880d681SAndroid Build Coastguard Worker        documentation on iterators for more.
158*9880d681SAndroid Build Coastguard Worker        """
159*9880d681SAndroid Build Coastguard Worker        symbols = lib.LLVMGetSymbols(self)
160*9880d681SAndroid Build Coastguard Worker        last = None
161*9880d681SAndroid Build Coastguard Worker        while True:
162*9880d681SAndroid Build Coastguard Worker            if lib.LLVMIsSymbolIteratorAtEnd(self, symbols):
163*9880d681SAndroid Build Coastguard Worker                break
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker            last = Symbol(symbols, self)
166*9880d681SAndroid Build Coastguard Worker            if cache:
167*9880d681SAndroid Build Coastguard Worker                last.cache()
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker            yield last
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker            lib.LLVMMoveToNextSymbol(symbols)
172*9880d681SAndroid Build Coastguard Worker            last.expire()
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker        if last is not None:
175*9880d681SAndroid Build Coastguard Worker            last.expire()
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker        lib.LLVMDisposeSymbolIterator(symbols)
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Workerclass Section(LLVMObject):
180*9880d681SAndroid Build Coastguard Worker    """Represents a section in an object file."""
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker    def __init__(self, ptr):
183*9880d681SAndroid Build Coastguard Worker        """Construct a new section instance.
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker        Section instances can currently only be created from an ObjectFile
186*9880d681SAndroid Build Coastguard Worker        instance. Therefore, this constructor should not be used outside of
187*9880d681SAndroid Build Coastguard Worker        this module.
188*9880d681SAndroid Build Coastguard Worker        """
189*9880d681SAndroid Build Coastguard Worker        LLVMObject.__init__(self, ptr)
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker        self.expired = False
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker    @CachedProperty
194*9880d681SAndroid Build Coastguard Worker    def name(self):
195*9880d681SAndroid Build Coastguard Worker        """Obtain the string name of the section.
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker        This is typically something like '.dynsym' or '.rodata'.
198*9880d681SAndroid Build Coastguard Worker        """
199*9880d681SAndroid Build Coastguard Worker        if self.expired:
200*9880d681SAndroid Build Coastguard Worker            raise Exception('Section instance has expired.')
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSectionName(self)
203*9880d681SAndroid Build Coastguard Worker
204*9880d681SAndroid Build Coastguard Worker    @CachedProperty
205*9880d681SAndroid Build Coastguard Worker    def size(self):
206*9880d681SAndroid Build Coastguard Worker        """The size of the section, in long bytes."""
207*9880d681SAndroid Build Coastguard Worker        if self.expired:
208*9880d681SAndroid Build Coastguard Worker            raise Exception('Section instance has expired.')
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSectionSize(self)
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Worker    @CachedProperty
213*9880d681SAndroid Build Coastguard Worker    def contents(self):
214*9880d681SAndroid Build Coastguard Worker        if self.expired:
215*9880d681SAndroid Build Coastguard Worker            raise Exception('Section instance has expired.')
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker        siz = self.size
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker        r = lib.LLVMGetSectionContents(self)
220*9880d681SAndroid Build Coastguard Worker        if r:
221*9880d681SAndroid Build Coastguard Worker            return string_at(r, siz)
222*9880d681SAndroid Build Coastguard Worker        return None
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker    @CachedProperty
225*9880d681SAndroid Build Coastguard Worker    def address(self):
226*9880d681SAndroid Build Coastguard Worker        """The address of this section, in long bytes."""
227*9880d681SAndroid Build Coastguard Worker        if self.expired:
228*9880d681SAndroid Build Coastguard Worker            raise Exception('Section instance has expired.')
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSectionAddress(self)
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker    def has_symbol(self, symbol):
233*9880d681SAndroid Build Coastguard Worker        """Returns whether a Symbol instance is present in this Section."""
234*9880d681SAndroid Build Coastguard Worker        if self.expired:
235*9880d681SAndroid Build Coastguard Worker            raise Exception('Section instance has expired.')
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Worker        assert isinstance(symbol, Symbol)
238*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSectionContainsSymbol(self, symbol)
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker    def get_relocations(self, cache=False):
241*9880d681SAndroid Build Coastguard Worker        """Obtain the relocations in this Section.
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker        This is a generator for llvm.object.Relocation instances.
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker        Each instance is a limited used object. See this module's documentation
246*9880d681SAndroid Build Coastguard Worker        on iterators for more.
247*9880d681SAndroid Build Coastguard Worker        """
248*9880d681SAndroid Build Coastguard Worker        if self.expired:
249*9880d681SAndroid Build Coastguard Worker            raise Exception('Section instance has expired.')
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker        relocations = lib.LLVMGetRelocations(self)
252*9880d681SAndroid Build Coastguard Worker        last = None
253*9880d681SAndroid Build Coastguard Worker        while True:
254*9880d681SAndroid Build Coastguard Worker            if lib.LLVMIsRelocationIteratorAtEnd(self, relocations):
255*9880d681SAndroid Build Coastguard Worker                break
256*9880d681SAndroid Build Coastguard Worker
257*9880d681SAndroid Build Coastguard Worker            last = Relocation(relocations)
258*9880d681SAndroid Build Coastguard Worker            if cache:
259*9880d681SAndroid Build Coastguard Worker                last.cache()
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Worker            yield last
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker            lib.LLVMMoveToNextRelocation(relocations)
264*9880d681SAndroid Build Coastguard Worker            last.expire()
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker        if last is not None:
267*9880d681SAndroid Build Coastguard Worker            last.expire()
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker        lib.LLVMDisposeRelocationIterator(relocations)
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker    def cache(self):
272*9880d681SAndroid Build Coastguard Worker        """Cache properties of this Section.
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker        This can be called as a workaround to the single active Section
275*9880d681SAndroid Build Coastguard Worker        limitation. When called, the properties of the Section are fetched so
276*9880d681SAndroid Build Coastguard Worker        they are still available after the Section has been marked inactive.
277*9880d681SAndroid Build Coastguard Worker        """
278*9880d681SAndroid Build Coastguard Worker        getattr(self, 'name')
279*9880d681SAndroid Build Coastguard Worker        getattr(self, 'size')
280*9880d681SAndroid Build Coastguard Worker        getattr(self, 'contents')
281*9880d681SAndroid Build Coastguard Worker        getattr(self, 'address')
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker    def expire(self):
284*9880d681SAndroid Build Coastguard Worker        """Expire the section.
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker        This is called internally by the section iterator.
287*9880d681SAndroid Build Coastguard Worker        """
288*9880d681SAndroid Build Coastguard Worker        self.expired = True
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Workerclass Symbol(LLVMObject):
291*9880d681SAndroid Build Coastguard Worker    """Represents a symbol in an object file."""
292*9880d681SAndroid Build Coastguard Worker    def __init__(self, ptr, object_file):
293*9880d681SAndroid Build Coastguard Worker        assert isinstance(ptr, c_object_p)
294*9880d681SAndroid Build Coastguard Worker        assert isinstance(object_file, ObjectFile)
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker        LLVMObject.__init__(self, ptr)
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker        self.expired = False
299*9880d681SAndroid Build Coastguard Worker        self._object_file = object_file
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker    @CachedProperty
302*9880d681SAndroid Build Coastguard Worker    def name(self):
303*9880d681SAndroid Build Coastguard Worker        """The str name of the symbol.
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker        This is often a function or variable name. Keep in mind that name
306*9880d681SAndroid Build Coastguard Worker        mangling could be in effect.
307*9880d681SAndroid Build Coastguard Worker        """
308*9880d681SAndroid Build Coastguard Worker        if self.expired:
309*9880d681SAndroid Build Coastguard Worker            raise Exception('Symbol instance has expired.')
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSymbolName(self)
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker    @CachedProperty
314*9880d681SAndroid Build Coastguard Worker    def address(self):
315*9880d681SAndroid Build Coastguard Worker        """The address of this symbol, in long bytes."""
316*9880d681SAndroid Build Coastguard Worker        if self.expired:
317*9880d681SAndroid Build Coastguard Worker            raise Exception('Symbol instance has expired.')
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSymbolAddress(self)
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker    @CachedProperty
322*9880d681SAndroid Build Coastguard Worker    def size(self):
323*9880d681SAndroid Build Coastguard Worker        """The size of the symbol, in long bytes."""
324*9880d681SAndroid Build Coastguard Worker        if self.expired:
325*9880d681SAndroid Build Coastguard Worker            raise Exception('Symbol instance has expired.')
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetSymbolSize(self)
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker    @CachedProperty
330*9880d681SAndroid Build Coastguard Worker    def section(self):
331*9880d681SAndroid Build Coastguard Worker        """The Section to which this Symbol belongs.
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker        The returned Section instance does not expire, unlike Sections that are
334*9880d681SAndroid Build Coastguard Worker        commonly obtained through iteration.
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker        Because this obtains a new section iterator each time it is accessed,
337*9880d681SAndroid Build Coastguard Worker        calling this on a number of Symbol instances could be expensive.
338*9880d681SAndroid Build Coastguard Worker        """
339*9880d681SAndroid Build Coastguard Worker        sections = lib.LLVMGetSections(self._object_file)
340*9880d681SAndroid Build Coastguard Worker        lib.LLVMMoveToContainingSection(sections, self)
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker        return Section(sections)
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker    def cache(self):
345*9880d681SAndroid Build Coastguard Worker        """Cache all cacheable properties."""
346*9880d681SAndroid Build Coastguard Worker        getattr(self, 'name')
347*9880d681SAndroid Build Coastguard Worker        getattr(self, 'address')
348*9880d681SAndroid Build Coastguard Worker        getattr(self, 'size')
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker    def expire(self):
351*9880d681SAndroid Build Coastguard Worker        """Mark the object as expired to prevent future API accesses.
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker        This is called internally by this module and it is unlikely that
354*9880d681SAndroid Build Coastguard Worker        external callers have a legitimate reason for using it.
355*9880d681SAndroid Build Coastguard Worker        """
356*9880d681SAndroid Build Coastguard Worker        self.expired = True
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Workerclass Relocation(LLVMObject):
359*9880d681SAndroid Build Coastguard Worker    """Represents a relocation definition."""
360*9880d681SAndroid Build Coastguard Worker    def __init__(self, ptr):
361*9880d681SAndroid Build Coastguard Worker        """Create a new relocation instance.
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker        Relocations are created from objects derived from Section instances.
364*9880d681SAndroid Build Coastguard Worker        Therefore, this constructor should not be called outside of this
365*9880d681SAndroid Build Coastguard Worker        module. See Section.get_relocations() for the proper method to obtain
366*9880d681SAndroid Build Coastguard Worker        a Relocation instance.
367*9880d681SAndroid Build Coastguard Worker        """
368*9880d681SAndroid Build Coastguard Worker        assert isinstance(ptr, c_object_p)
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker        LLVMObject.__init__(self, ptr)
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker        self.expired = False
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Worker    @CachedProperty
375*9880d681SAndroid Build Coastguard Worker    def offset(self):
376*9880d681SAndroid Build Coastguard Worker        """The offset of this relocation, in long bytes."""
377*9880d681SAndroid Build Coastguard Worker        if self.expired:
378*9880d681SAndroid Build Coastguard Worker            raise Exception('Relocation instance has expired.')
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetRelocationOffset(self)
381*9880d681SAndroid Build Coastguard Worker
382*9880d681SAndroid Build Coastguard Worker    @CachedProperty
383*9880d681SAndroid Build Coastguard Worker    def symbol(self):
384*9880d681SAndroid Build Coastguard Worker        """The Symbol corresponding to this Relocation."""
385*9880d681SAndroid Build Coastguard Worker        if self.expired:
386*9880d681SAndroid Build Coastguard Worker            raise Exception('Relocation instance has expired.')
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Worker        ptr = lib.LLVMGetRelocationSymbol(self)
389*9880d681SAndroid Build Coastguard Worker        return Symbol(ptr)
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Worker    @CachedProperty
392*9880d681SAndroid Build Coastguard Worker    def type_number(self):
393*9880d681SAndroid Build Coastguard Worker        """The relocation type, as a long."""
394*9880d681SAndroid Build Coastguard Worker        if self.expired:
395*9880d681SAndroid Build Coastguard Worker            raise Exception('Relocation instance has expired.')
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetRelocationType(self)
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker    @CachedProperty
400*9880d681SAndroid Build Coastguard Worker    def type_name(self):
401*9880d681SAndroid Build Coastguard Worker        """The relocation type's name, as a str."""
402*9880d681SAndroid Build Coastguard Worker        if self.expired:
403*9880d681SAndroid Build Coastguard Worker            raise Exception('Relocation instance has expired.')
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetRelocationTypeName(self)
406*9880d681SAndroid Build Coastguard Worker
407*9880d681SAndroid Build Coastguard Worker    @CachedProperty
408*9880d681SAndroid Build Coastguard Worker    def value_string(self):
409*9880d681SAndroid Build Coastguard Worker        if self.expired:
410*9880d681SAndroid Build Coastguard Worker            raise Exception('Relocation instance has expired.')
411*9880d681SAndroid Build Coastguard Worker
412*9880d681SAndroid Build Coastguard Worker        return lib.LLVMGetRelocationValueString(self)
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker    def expire(self):
415*9880d681SAndroid Build Coastguard Worker        """Expire this instance, making future API accesses fail."""
416*9880d681SAndroid Build Coastguard Worker        self.expired = True
417*9880d681SAndroid Build Coastguard Worker
418*9880d681SAndroid Build Coastguard Worker    def cache(self):
419*9880d681SAndroid Build Coastguard Worker        """Cache all cacheable properties on this instance."""
420*9880d681SAndroid Build Coastguard Worker        getattr(self, 'address')
421*9880d681SAndroid Build Coastguard Worker        getattr(self, 'offset')
422*9880d681SAndroid Build Coastguard Worker        getattr(self, 'symbol')
423*9880d681SAndroid Build Coastguard Worker        getattr(self, 'type')
424*9880d681SAndroid Build Coastguard Worker        getattr(self, 'type_name')
425*9880d681SAndroid Build Coastguard Worker        getattr(self, 'value_string')
426*9880d681SAndroid Build Coastguard Worker
427*9880d681SAndroid Build Coastguard Workerdef register_library(library):
428*9880d681SAndroid Build Coastguard Worker    """Register function prototypes with LLVM library instance."""
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker    # Object.h functions
431*9880d681SAndroid Build Coastguard Worker    library.LLVMCreateObjectFile.argtypes = [MemoryBuffer]
432*9880d681SAndroid Build Coastguard Worker    library.LLVMCreateObjectFile.restype = c_object_p
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Worker    library.LLVMDisposeObjectFile.argtypes = [ObjectFile]
435*9880d681SAndroid Build Coastguard Worker
436*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSections.argtypes = [ObjectFile]
437*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSections.restype = c_object_p
438*9880d681SAndroid Build Coastguard Worker
439*9880d681SAndroid Build Coastguard Worker    library.LLVMDisposeSectionIterator.argtypes = [c_object_p]
440*9880d681SAndroid Build Coastguard Worker
441*9880d681SAndroid Build Coastguard Worker    library.LLVMIsSectionIteratorAtEnd.argtypes = [ObjectFile, c_object_p]
442*9880d681SAndroid Build Coastguard Worker    library.LLVMIsSectionIteratorAtEnd.restype = bool
443*9880d681SAndroid Build Coastguard Worker
444*9880d681SAndroid Build Coastguard Worker    library.LLVMMoveToNextSection.argtypes = [c_object_p]
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker    library.LLVMMoveToContainingSection.argtypes = [c_object_p, c_object_p]
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbols.argtypes = [ObjectFile]
449*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbols.restype = c_object_p
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker    library.LLVMDisposeSymbolIterator.argtypes = [c_object_p]
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker    library.LLVMIsSymbolIteratorAtEnd.argtypes = [ObjectFile, c_object_p]
454*9880d681SAndroid Build Coastguard Worker    library.LLVMIsSymbolIteratorAtEnd.restype = bool
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker    library.LLVMMoveToNextSymbol.argtypes = [c_object_p]
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionName.argtypes = [c_object_p]
459*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionName.restype = c_char_p
460*9880d681SAndroid Build Coastguard Worker
461*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionSize.argtypes = [c_object_p]
462*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionSize.restype = c_uint64
463*9880d681SAndroid Build Coastguard Worker
464*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionContents.argtypes = [c_object_p]
465*9880d681SAndroid Build Coastguard Worker    # Can't use c_char_p here as it isn't a NUL-terminated string.
466*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionContents.restype = POINTER(c_char)
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionAddress.argtypes = [c_object_p]
469*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionAddress.restype = c_uint64
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionContainsSymbol.argtypes = [c_object_p, c_object_p]
472*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSectionContainsSymbol.restype = bool
473*9880d681SAndroid Build Coastguard Worker
474*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocations.argtypes = [c_object_p]
475*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocations.restype = c_object_p
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker    library.LLVMDisposeRelocationIterator.argtypes = [c_object_p]
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Worker    library.LLVMIsRelocationIteratorAtEnd.argtypes = [c_object_p, c_object_p]
480*9880d681SAndroid Build Coastguard Worker    library.LLVMIsRelocationIteratorAtEnd.restype = bool
481*9880d681SAndroid Build Coastguard Worker
482*9880d681SAndroid Build Coastguard Worker    library.LLVMMoveToNextRelocation.argtypes = [c_object_p]
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbolName.argtypes = [Symbol]
485*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbolName.restype = c_char_p
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbolAddress.argtypes = [Symbol]
488*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbolAddress.restype = c_uint64
489*9880d681SAndroid Build Coastguard Worker
490*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbolSize.argtypes = [Symbol]
491*9880d681SAndroid Build Coastguard Worker    library.LLVMGetSymbolSize.restype = c_uint64
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationOffset.argtypes = [c_object_p]
494*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationOffset.restype = c_uint64
495*9880d681SAndroid Build Coastguard Worker
496*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationSymbol.argtypes = [c_object_p]
497*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationSymbol.restype = c_object_p
498*9880d681SAndroid Build Coastguard Worker
499*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationType.argtypes = [c_object_p]
500*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationType.restype = c_uint64
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationTypeName.argtypes = [c_object_p]
503*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationTypeName.restype = c_char_p
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationValueString.argtypes = [c_object_p]
506*9880d681SAndroid Build Coastguard Worker    library.LLVMGetRelocationValueString.restype = c_char_p
507*9880d681SAndroid Build Coastguard Worker
508*9880d681SAndroid Build Coastguard Workerlib = get_library()
509*9880d681SAndroid Build Coastguard Workerregister_library(lib)
510