def check_datafile(filename): """ Verify that the reassembling the output of the disassembler produces the same binary, and that disassembling the output of the assembler produces the same text. """ data = testdata.read(filename) if 'asm' not in data: raise SkipTest("no asm section in datafile") assembled = ebpf.assembler.assemble(data['asm']) disassembled = ebpf.disassembler.disassemble(assembled) reassembled = ebpf.assembler.assemble(disassembled) disassembled2 = ebpf.disassembler.disassemble(reassembled) if disassembled != disassembled2: diff = difflib.unified_diff(disassembled.splitlines(), disassembled2.splitlines(), lineterm="") formatted = ''.join(' %s\n' % x for x in diff) raise AssertionError("Assembly differs:\n%s" % formatted) if assembled != reassembled: raise AssertionError("binary differs")
def check_datafile(filename): """ Given assembly source code and an expected result, run the eBPF program and verify that the result matches. """ data = testdata.read(filename) if 'asm' not in data and 'raw' not in data: raise SkipTest("no asm or raw section in datafile") if 'result' not in data and 'error' not in data and 'error pattern' not in data: raise SkipTest("no result or error section in datafile") if not os.path.exists(VM): raise SkipTest("VM not found") if 'raw' in data: code = ''.join(struct.pack("=Q", x) for x in data['raw']) else: code = ubpf.assembler.assemble(data['asm']) memfile = None cmd = [VM] if 'mem' in data: memfile = tempfile.NamedTemporaryFile() memfile.write(data['mem']) memfile.flush() cmd.extend(['-m', memfile.name]) cmd.append('-') vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = vm.communicate(code) stderr = stderr.strip() if memfile: memfile.close() if 'error' in data: if data['error'] != stderr: raise AssertionError("Expected error %r, got %r" % (data['error'], stderr)) elif 'error pattern' in data: if not re.search(data['error pattern'], stderr): raise AssertionError("Expected error matching %r, got %r" % (data['error pattern'], stderr)) else: if stderr: raise AssertionError("Unexpected error %r" % stderr) if 'result' in data: if vm.returncode != 0: raise AssertionError("VM exited with status %d, stderr=%r" % (vm.returncode, stderr)) expected = int(data['result'], 0) result = int(stdout, 0) if expected != result: raise AssertionError("Expected result 0x%x, got 0x%x, stderr=%r" % (expected, result, stderr)) else: if vm.returncode == 0: raise AssertionError("Expected VM to exit with an error code")
def main(): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('name') parser.add_argument('path') args = parser.parse_args() data = testdata.read(args.name + '.data') assert data if not os.path.isdir(args.path): os.makedirs(args.path) def writefile(name, contents): file("%s/%s" % (args.path, name), "w").write(contents) if 'mem' in data: writefile('mem', data['mem']) # Probably a packet, so write out a pcap file writefile( 'pcap', struct.pack( '=IHHIIIIIIII', 0xa1b2c3d4, # magic 2, 4, # version 0, # time zone offset 0, # time stamp accuracy 65535, # snapshot length 1, # link layer type 0, 0, # timestamp len(data['mem']), # length len(data['mem'])) # length + data['mem']) if 'raw' in data: code = ''.join(struct.pack("=Q", x) for x in data['raw']) elif 'asm' in data: code = ebpf.assembler.assemble(data['asm']) else: code = None if code: writefile('code', code) if 'asm' in data: writefile('asm', data['asm']) elif code: writefile('asm', ebpf.disassembler.disassemble(code))
def main(): parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('name') parser.add_argument('path') args = parser.parse_args() data = testdata.read(args.name + '.data') assert data if not os.path.isdir(args.path): os.makedirs(args.path) def writefile(name, contents): file("%s/%s" % (args.path, name), "w").write(contents) if 'mem' in data: writefile('mem', data['mem']) # Probably a packet, so write out a pcap file writefile('pcap', struct.pack('=IHHIIIIIIII', 0xa1b2c3d4, # magic 2, 4, # version 0, # time zone offset 0, # time stamp accuracy 65535, # snapshot length 1, # link layer type 0, 0, # timestamp len(data['mem']), # length len(data['mem'])) # length + data['mem']) if 'raw' in data: code = ''.join(struct.pack("=Q", x) for x in data['raw']) elif 'asm' in data: code = ubpf.assembler.assemble(data['asm']) else: code = None if code: writefile('code', code) if 'asm' in data: writefile('asm', data['asm']) elif code: writefile('asm', ubpf.disassembler.disassemble(code)) if 'pyelf' in data: from test_elf import generate_elf elf = generate_elf(data['pyelf']) writefile('elf', elf)
def check_datafile(filename): """ """ data = testdata.read(filename) if 'pyelf' not in data: raise SkipTest("no pyelf section in datafile") if 'result' not in data and 'error' not in data and 'error pattern' not in data: raise SkipTest("no result or error section in datafile") if not os.path.exists(VM): raise SkipTest("VM not found") elf = generate_elf(data['pyelf']) cmd = [VM] cmd.append('-') vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = vm.communicate(elf) stdout = stdout.decode("utf-8") stderr = stderr.decode("utf-8") stderr = stderr.strip() if 'error' in data: if data['error'] != stderr: raise AssertionError("Expected error %r, got %r" % (data['error'], stderr)) elif 'error pattern' in data: if not re.search(data['error pattern'], stderr): raise AssertionError("Expected error matching %r, got %r" % (data['error pattern'], stderr)) else: if stderr: raise AssertionError("Unexpected error %r" % stderr) if 'result' in data: if vm.returncode != 0: raise AssertionError("VM exited with status %d, stderr=%r" % (vm.returncode, stderr)) expected = int(data['result'], 0) result = int(stdout, 0) if expected != result: raise AssertionError("Expected result 0x%x, got 0x%x, stderr=%r" % (expected, result, stderr)) else: if vm.returncode == 0: raise AssertionError("Expected VM to exit with an error code")
def check_datafile(filename): """ Verify that the result of disassembling the 'raw' section matches the 'asm' section. """ data = testdata.read(filename) if 'asm' not in data: raise SkipTest("no asm section in datafile") if 'raw' not in data: raise SkipTest("no raw section in datafile") binary = ''.join(struct.pack("=Q", x) for x in data['raw']) result = ubpf.disassembler.disassemble(binary) # TODO strip whitespace and comments from asm if result.strip() != data['asm'].strip(): diff = difflib.unified_diff(data['asm'].splitlines(), result.splitlines(), lineterm="") formatted = ''.join(' %s\n' % x for x in diff) raise AssertionError("Assembly differs:\n%s" % formatted)
def check_datafile(filename): """ """ data = testdata.read(filename) if 'pyelf' not in data: raise SkipTest("no pyelf section in datafile") if 'result' not in data and 'error' not in data and 'error pattern' not in data: raise SkipTest("no result or error section in datafile") if not os.path.exists(VM): raise SkipTest("VM not found") elf = generate_elf(data['pyelf']) cmd = [VM] cmd.append('-') vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = vm.communicate(elf) stderr = stderr.strip() if 'error' in data: if data['error'] != stderr: raise AssertionError("Expected error %r, got %r" % (data['error'], stderr)) elif 'error pattern' in data: if not re.search(data['error pattern'], stderr): raise AssertionError("Expected error matching %r, got %r" % (data['error pattern'], stderr)) else: if stderr: raise AssertionError("Unexpected error %r" % stderr) if 'result' in data: if vm.returncode != 0: raise AssertionError("VM exited with status %d, stderr=%r" % (vm.returncode, stderr)) expected = int(data['result'], 0) result = int(stdout, 0) if expected != result: raise AssertionError("Expected result 0x%x, got 0x%x, stderr=%r" % (expected, result, stderr)) else: if vm.returncode == 0: raise AssertionError("Expected VM to exit with an error code")
def check_datafile(filename): """ Verify that the result of assembling the 'asm' section matches the 'raw' section. """ data = testdata.read(filename) if 'asm' not in data: raise SkipTest("no asm section in datafile") if 'raw' not in data: raise SkipTest("no raw section in datafile") bin_result = ubpf.assembler.assemble(data['asm']) assert len(bin_result) % 8 == 0 assert len(bin_result) / 8 == len(data['raw']) for i in xrange(0, len(bin_result), 8): j = int(i/8) inst, = struct.unpack_from("=Q", bin_result[i:i+8]) exp = data['raw'][j] if exp != inst: raise AssertionError("Expected instruction %d to be %#x (%s), but was %#x (%s)" % (j, exp, try_disassemble(exp), inst, try_disassemble(inst)))
def check_datafile(filename): """ Verify that the result of assembling the 'asm' section matches the 'raw' section. """ data = testdata.read(filename) if 'asm' not in data: raise SkipTest("no asm section in datafile") if 'raw' not in data: raise SkipTest("no raw section in datafile") bin_result = ubpf.assembler.assemble(data['asm']) assert len(bin_result) % 8 == 0 assert len(bin_result) / 8 == len(data['raw']) for i in xrange(0, len(bin_result), 8): j = i/8 inst, = struct.unpack_from("=Q", bin_result[i:i+8]) exp = data['raw'][j] if exp != inst: raise AssertionError("Expected instruction %d to be %#x (%s), but was %#x (%s)" % (j, exp, try_disassemble(exp), inst, try_disassemble(inst)))
def check_datafile(filename): """ Verify that the reassembling the output of the disassembler produces the same binary, and that disassembling the output of the assembler produces the same text. """ data = testdata.read(filename) if 'asm' not in data: raise SkipTest("no asm section in datafile") assembled = ubpf.assembler.assemble(data['asm']) disassembled = ubpf.disassembler.disassemble(assembled) reassembled = ubpf.assembler.assemble(disassembled) disassembled2 = ubpf.disassembler.disassemble(reassembled) if disassembled != disassembled2: diff = difflib.unified_diff(disassembled.splitlines(), disassembled2.splitlines(), lineterm="") formatted = ''.join(' %s\n' % x for x in diff) raise AssertionError("Assembly differs:\n%s" % formatted) if assembled != reassembled: raise AssertionError("binary differs")
def check_datafile(filename): """ Given assembly source code and an expected result, run the eBPF program and verify that the result matches. Uses the JIT compiler. """ data = testdata.read(filename) if 'asm' not in data and 'raw' not in data: raise SkipTest("no asm or raw section in datafile") if 'result' not in data and 'error' not in data and 'error pattern' not in data: raise SkipTest("no result or error section in datafile") if not os.path.exists(VM): raise SkipTest("VM not found") if 'no jit' in data: raise SkipTest("JIT disabled for this testcase (%s)" % data['no jit']) if 'raw' in data: code = b''.join(struct.pack("=Q", x) for x in data['raw']) else: code = ubpf.assembler.assemble(data['asm']) memfile = None if 'mem' in data: memfile = tempfile.NamedTemporaryFile() memfile.write(data['mem']) memfile.flush() num_register_offsets = 20 if 'no register offset' in data: # The JIT relies on a fixed register mapping for the call instruction num_register_offsets = 1 try: for register_offset in xrange(0, num_register_offsets): cmd = [VM] if memfile: cmd.extend(['-m', memfile.name]) if 'reload' in data: cmd.extend(['-R']) if 'unload' in data: cmd.extend(['-U']) cmd.extend(['-j', '-r', str(register_offset), '-']) vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = vm.communicate(code) stdout = stdout.decode("utf-8") stderr = stderr.decode("utf-8") stderr = stderr.strip() if 'error' in data: if data['error'] != stderr: raise AssertionError("Expected error %r, got %r" % (data['error'], stderr)) elif 'error pattern' in data: if not re.search(data['error pattern'], stderr): raise AssertionError("Expected error matching %r, got %r" % (data['error pattern'], stderr)) else: if stderr: raise AssertionError("Unexpected error %r" % stderr) if 'result' in data: if vm.returncode != 0: raise AssertionError("VM exited with status %d, stderr=%r" % (vm.returncode, stderr)) expected = int(data['result'], 0) result = int(stdout, 0) if expected != result: raise AssertionError("Expected result 0x%x, got 0x%x, stderr=%r" % (expected, result, stderr)) else: if vm.returncode == 0: raise AssertionError("Expected VM to exit with an error code") finally: if memfile: memfile.close()
def check_datafile(filename): """ Given assembly source code and an expected result, run the eBPF program and verify that the result matches. Uses the JIT compiler. """ data = testdata.read(filename) if 'asm' not in data and 'raw' not in data: raise SkipTest("no asm or raw section in datafile") if 'result' not in data and 'error' not in data and 'error pattern' not in data: raise SkipTest("no result or error section in datafile") if not os.path.exists(VM): raise SkipTest("VM not found") if 'no jit' in data: raise SkipTest("JIT disabled for this testcase (%s)" % data['no jit']) if 'raw' in data: code = ''.join(struct.pack("=Q", x) for x in data['raw']) else: code = ubpf.assembler.assemble(data['asm']) memfile = None if 'mem' in data: memfile = tempfile.NamedTemporaryFile() memfile.write(data['mem']) memfile.flush() num_register_offsets = 20 if 'no register offset' in data: # The JIT relies on a fixed register mapping for the call instruction num_register_offsets = 1 try: for register_offset in xrange(0, num_register_offsets): cmd = [VM] if memfile: cmd.extend(['-m', memfile.name]) cmd.extend(['-j', '-r', str(register_offset), '-']) vm = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = vm.communicate(code) stderr = stderr.strip() if 'error' in data: if data['error'] != stderr: raise AssertionError("Expected error %r, got %r" % (data['error'], stderr)) elif 'error pattern' in data: if not re.search(data['error pattern'], stderr): raise AssertionError("Expected error matching %r, got %r" % (data['error pattern'], stderr)) else: if stderr: raise AssertionError("Unexpected error %r" % stderr) if 'result' in data: if vm.returncode != 0: raise AssertionError("VM exited with status %d, stderr=%r" % (vm.returncode, stderr)) expected = int(data['result'], 0) result = int(stdout, 0) if expected != result: raise AssertionError("Expected result 0x%x, got 0x%x, stderr=%r" % (expected, result, stderr)) else: if vm.returncode == 0: raise AssertionError("Expected VM to exit with an error code") finally: if memfile: memfile.close()