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