def test_pack_bits_bigger_base(self): self.assertEqual( pack_bits( 0b100000000000, ((2, 0), 3), ((10, 7), 15), ((4, 4), 1), ), 0b111110010011)
def _resolve_labels(self): for address in self.labels_addresses: data = self.labels_addresses[address] label = data['label'] relative = data.get('relative', False) absolute_address = self.get_label_absolute_address_by_name(label) if not relative: true_address = absolute_address else: true_address = self.get_label_relative_address_by_name( label, data['start']) if true_address is None: raise UnknownLabel(label) if 'hook' in data: data['hook'](address, true_address) continue if 'filter' in data: true_address = data['filter'](true_address) if 'alignment' in data: if absolute_address % data['alignment'] != 0: raise AlignmentError(label) size = data['size'] total_bits = size * 8 if 'bits' in data: total_bits = data['bits'][0] - data['bits'][1] + 1 bits_to_check = data.get('bits_check', total_bits) if relative: if not in_bit_range_signed(true_address, bits_to_check): raise NotInBitRange(true_address, bits_to_check, label) else: if true_address < 0 or not in_bit_range( true_address, bits_to_check): raise NotInBitRange(true_address, bits_to_check, label) if 'post_filter' in data: true_address = data['post_filter'](true_address) if 'bits' in data: true_address = pack_bits( 0, (data['bits'], true_address, relative), check_bits='bits_check' not in data) for i in range(0, size): value = (true_address >> (8 * i)) & 0xFF self.assembled_bytes[address + i] |= value
def _resolve_labels(self, linker): for address in self.labels_addresses: data = self.labels_addresses[address] label = data.label is_relative = data.relative != 0 absolute_address = self.get_label_absolute_address_by_name(label) if not is_relative: true_address = absolute_address else: true_address = self.get_label_relative_address_by_name( label, data.relative) if true_address is None: true_address = linker.resolve_unknown_symbol( self, address, data) absolute_address = true_address if data.hook: data.hook(address, true_address) continue if absolute_address % data.alignment != 0: raise AlignmentError(label) size = data.size total_bits = data.bits_size if not is_relative and true_address < 0: raise OnlyForwardAddressesAllowed(label, true_address) if not in_bit_range_decimal( true_address, total_bits, signed=is_relative): raise NotInBitRange(true_address, total_bits, label) if data.filter: true_address = data.filter(true_address) if data.bits: true_address = pack_bits(0, (data.bits, true_address)) for i in range(0, size): value = (true_address >> (8 * i)) & 0xFF if self.big_endian: self.assembled_bytes[address + ((size - 1) - i)] |= value else: self.assembled_bytes[address + i] |= value if self.log: print('label "{0}" translated to ({1}) at address {2}'.format( label, ','.join([ '0x{0:02x}'.format(x) for x in self.assembled_bytes[address:address + size] ]), hex(address)))
def _build_modrm(assembler, modrm): blob = pack_byte(pack_bits(0, ((7, 6), modrm['mod']), ((5, 3), modrm['reg']), ((2, 0), modrm['rm']))) if modrm.get('displacement') is not None: blob += pack_le16s(assembler.parse_integer_or_label( modrm['displacement'].lstrip('+'), size=2, bits_size=16, offset=1, signed=True)) return blob
def test_pack_bits(self): self.assertEqual(pack_bits(0b00000000000, ((2, 0), 3), ((10, 7), 15)), 0b11110000011)
def test_pack_bits_signed(self): self.assertEqual(pack_bits(0b00000000000, ((2, 0), -2), ((10, 7), 15)), 0b11110000110)
def _build_opcode(self, base, *args): value = pack_bits(base, *args) if self.big_endian: return pack_be32u(value) return pack_le32u(value)