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