1"""Abstraction layer for different ABIs.""" 2 3import re 4import symbol 5 6def UnpackLittleEndian(word): 7 """Split a hexadecimal string in little endian order.""" 8 return [word[x:x+2] for x in range(len(word) - 2, -2, -2)] 9 10 11ASSEMBLE = 'as' 12DISASSEMBLE = 'objdump' 13LINK = 'ld' 14UNPACK = 'unpack' 15 16OPTIONS = { 17 'x86': { 18 ASSEMBLE: ['--32'], 19 LINK: ['-melf_i386'] 20 } 21} 22 23 24class Architecture(object): 25 """Creates an architecture abstraction for a given ABI. 26 27 Args: 28 name: The abi name, as represented in a tombstone. 29 """ 30 31 def __init__(self, name): 32 symbol.ARCH = name 33 self.toolchain = symbol.FindToolchain() 34 self.options = OPTIONS.get(name, {}) 35 36 def Assemble(self, args): 37 """Generates an assembler command, appending the given args.""" 38 return [symbol.ToolPath(ASSEMBLE)] + self.options.get(ASSEMBLE, []) + args 39 40 def Link(self, args): 41 """Generates a link command, appending the given args.""" 42 return [symbol.ToolPath(LINK)] + self.options.get(LINK, []) + args 43 44 def Disassemble(self, args): 45 """Generates a disassemble command, appending the given args.""" 46 return ([symbol.ToolPath(DISASSEMBLE)] + self.options.get(DISASSEMBLE, []) + 47 args) 48 49 def WordToBytes(self, word): 50 """Unpacks a hexadecimal string in the architecture's byte order. 51 52 Args: 53 word: A string representing a hexadecimal value. 54 55 Returns: 56 An array of hexadecimal byte values. 57 """ 58 return self.options.get(UNPACK, UnpackLittleEndian)(word) 59