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 test_rewriting(self
):
123 // Instructions to be rewritten
143 and $0xffffffe0, %eax
145 and $0xffffffe0, %ebx
147 and $0xffffffe0, %ecx
149 and $0xffffffe0, %edx
152 and $0xffffffe0, %eax
154 and $0xffffffe0, %ebx
156 and $0xffffffe0, %ecx
158 and $0xffffffe0, %edx
162 // These should be left alone
167 obj_file
= self
._assemble
(original
+ leave_alone
)
168 obj_file_expect
= self
._assemble
(rewritten
+ leave_alone
)
169 subprocess
.check_call(["ncrewrite", obj_file
])
170 if read_file(obj_file
) != read_file(obj_file_expect
):
171 raise Exception("Unexpected output:\n%s\nExpected:\n%s" %
172 (self
._disassemble
(obj_file
),
173 self
._disassemble
(obj_file_expect
)))
175 def test_rewriting_missing_nops(self
):
177 // Not enough preceding nops to rewrite
181 obj_file
= self
._assemble
(input_data
* 2)
182 original
= read_file(obj_file
)
183 proc
= subprocess
.Popen(["ncrewrite", obj_file
], stderr
=subprocess
.PIPE
)
184 stderr
= proc
.communicate()[1]
185 self
.assertEquals(stderr
,
186 "00000002: missing nops\n"
187 "00000006: missing nops\n")
188 self
.assertEquals(proc
.wait(), 0)
189 # Object file should not have been changed.
190 self
.assertEquals(original
, read_file(obj_file
))
193 if __name__
== "__main__":