11 def write_file(filename
, data
):
12 fh
= open(filename
, "w")
19 def read_file(filename
):
20 fh
= open(filename
, "r")
27 class TempDirTestCase(unittest
.TestCase
):
30 self
._on
_teardown
= []
32 def make_temp_dir(self
):
33 temp_dir
= tempfile
.mkdtemp(prefix
="tmp-%s-" % self
.__class
__.__name
__)
35 shutil
.rmtree(temp_dir
)
36 self
._on
_teardown
.append(tear_down
)
40 for func
in reversed(self
._on
_teardown
):
44 class NcValTest(TempDirTestCase
):
46 def assertEquals(self
, x
, y
):
48 if type(x
) == str and type(y
) == str:
49 raise AssertionError('"%s"\n!="%s"' % (x
, y
))
50 raise AssertionError("%r != %r" % (x
, y
))
52 def _get_errors(self
, obj_file
):
53 proc
= subprocess
.Popen(["ncval", obj_file
], stdout
=subprocess
.PIPE
)
54 lines
= [line
for line
in proc
.stdout
55 if line
.startswith("VALIDATOR")]
56 self
.assertEquals(proc
.wait(), 0)
59 def test_stub_out(self
):
60 asm_file
= os
.path
.join(self
.make_temp_dir(), "example.S")
61 obj_file
= os
.path
.join(self
.make_temp_dir(), "example")
62 write_file(asm_file
, """
71 subprocess
.check_call(["nacl-gcc", "-nostartfiles", asm_file
,
73 self
.assertEquals("".join(self
._get
_errors
(obj_file
)), """\
74 VALIDATOR: 00010000 (00001000:?): Jump target out of range
75 VALIDATOR: 00010005 (00001005:2): Unsafe indirect jump
76 VALIDATOR: 00010007 (00001007:3): Bad prefix
77 VALIDATOR: 00010007 (00001007:3): Illegal instruction
78 VALIDATOR: 0001000a (0000100a:1): Illegal instruction
79 VALIDATOR: 0001000b (0000100b:2): Illegal instruction
81 ncval_stubout
.main([obj_file
])
82 # Can't stub out bad jumps yet
83 self
.assertEquals("".join(self
._get
_errors
(obj_file
)), """\
84 VALIDATOR: 00010000 (00001000:?): Jump target out of range
87 def test_multiple_sections(self
):
88 # Check that we handle file indexes correctly in the presence
89 # of multiple ELF sections.
90 asm_file
= os
.path
.join(self
.make_temp_dir(), "example.S")
91 obj_file
= os
.path
.join(self
.make_temp_dir(), "example")
92 write_file(asm_file
, """
97 .section .fini, "x", @progbits
100 subprocess
.check_call(["nacl-gcc", "-nostartfiles", asm_file
,
102 self
.assertNotEquals(self
._get
_errors
(obj_file
), [])
103 ncval_stubout
.main([obj_file
])
104 self
.assertEquals(self
._get
_errors
(obj_file
), [])
107 class JumpRewriterTest(TempDirTestCase
):
109 def _assemble(self
, asm_source
):
110 asm_file
= os
.path
.join(self
.make_temp_dir(), "foo.S")
111 obj_file
= os
.path
.join(self
.make_temp_dir(), "foo.o")
112 write_file(asm_file
, asm_source
)
113 subprocess
.check_call(["gcc", "-c", asm_file
, "-o", obj_file
])
116 def _disassemble(self
, obj_file
):
117 proc
= subprocess
.Popen(["objdump", "-d", obj_file
],
118 stdout
=subprocess
.PIPE
)
119 return proc
.communicate()[0]
121 def assert_object_files_equal(self
, obj_file
, obj_file_expect
):
122 if read_file(obj_file
) != read_file(obj_file_expect
):
123 raise AssertionError("Unexpected output:\n%s\nExpected:\n%s" %
124 (self
._disassemble
(obj_file
),
125 self
._disassemble
(obj_file_expect
)))
127 def test_rewriting(self
):
129 // Instructions to be rewritten
149 and $0xffffffe0, %eax
151 and $0xffffffe0, %ebx
153 and $0xffffffe0, %ecx
155 and $0xffffffe0, %edx
158 and $0xffffffe0, %eax
160 and $0xffffffe0, %ebx
162 and $0xffffffe0, %ecx
164 and $0xffffffe0, %edx
168 // These should be left alone
173 obj_file
= self
._assemble
(original
+ leave_alone
)
174 obj_file_expect
= self
._assemble
(rewritten
+ leave_alone
)
175 subprocess
.check_call(["ncrewrite", obj_file
])
176 self
.assert_object_files_equal(obj_file
, obj_file_expect
)
178 obj_file
= self
._assemble
(rewritten
+ leave_alone
)
179 obj_file_expect
= self
._assemble
(original
+ leave_alone
)
180 subprocess
.check_call(["ncrewrite", "--nop", obj_file
])
181 self
.assert_object_files_equal(obj_file
, obj_file_expect
)
183 def test_rewriting_missing_nops(self
):
185 // Not enough preceding nops to rewrite
189 obj_file
= self
._assemble
(input_data
* 2)
190 original
= read_file(obj_file
)
191 proc
= subprocess
.Popen(["ncrewrite", obj_file
], stderr
=subprocess
.PIPE
)
192 stderr
= proc
.communicate()[1]
193 self
.assertEquals(stderr
,
194 "00000002: cannot rewrite\n"
195 "00000006: cannot rewrite\n")
196 self
.assertEquals(proc
.wait(), 0)
197 # Object file should not have been changed.
198 self
.assertEquals(original
, read_file(obj_file
))
201 if __name__
== "__main__":