OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/eh-frame.h" | |
6 #include "testing/gtest/include/gtest/gtest.h" | |
7 | |
8 // Test enabled only on supported architectures. | |
9 #if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_ARM) || \ | |
10 defined(V8_TARGET_ARCH_ARM64) | |
11 | |
12 namespace { | |
13 | |
14 class EhFrameWriterTest : public testing::Test { | |
15 protected: | |
16 // Being a 7bit positive integer, this also serves as its ULEB128 encoding. | |
17 static const int kTestRegisterCode = 0; | |
Stefano Sanfilippo
2016/07/05 19:53:56
The problem with using different values here is th
rmcilroy
2016/07/06 13:59:30
I guess this is fine then, thanks for the explinat
| |
18 }; | |
19 | |
20 STATIC_CONST_MEMBER_DEFINITION const int EhFrameWriterTest::kTestRegisterCode; | |
21 | |
22 } // namespace | |
23 | |
24 using namespace v8::internal; | |
25 | |
26 TEST_F(EhFrameWriterTest, Alignment) { | |
27 EhFrameWriter writer; | |
28 writer.AdvanceLocation(42); | |
29 writer.Finish(100); | |
30 | |
31 EhFrameIterator iterator(&writer); | |
32 ASSERT_EQ(0, EhFrameHdr::kRecordSize % 4); | |
33 ASSERT_EQ(0, EhFrameWriter::kEhFrameTerminatorSize % 4); | |
34 EXPECT_EQ(0, (iterator.GetBufferSize() - EhFrameHdr::kRecordSize - | |
35 EhFrameWriter::kEhFrameTerminatorSize) % | |
36 8); | |
37 } | |
38 | |
39 TEST_F(EhFrameWriterTest, FDEHeader) { | |
40 static const int kProcedureSize = 0x5678abcd; | |
41 | |
42 EhFrameWriter writer; | |
43 writer.Finish(kProcedureSize); | |
44 | |
45 EhFrameIterator iterator(&writer); | |
46 int cie_size = iterator.GetNextUInt32(); | |
47 iterator.Skip(cie_size); | |
48 | |
49 int fde_size = iterator.GetNextUInt32(); | |
50 EXPECT_EQ(iterator.GetBufferSize(), | |
51 fde_size + cie_size + EhFrameWriter::kEhFrameTerminatorSize + | |
52 EhFrameHdr::kRecordSize + 2 * kInt32Size); | |
53 | |
54 int backwards_offset_to_cie_offset = iterator.GetCurrentOffset(); | |
55 int backwards_offset_to_cie = iterator.GetNextUInt32(); | |
56 EXPECT_EQ(backwards_offset_to_cie_offset, backwards_offset_to_cie); | |
57 | |
58 int procedure_address_offset = iterator.GetCurrentOffset(); | |
59 int procedure_address = iterator.GetNextUInt32(); | |
60 EXPECT_EQ(-(procedure_address_offset + RoundUp(kProcedureSize, 8)), | |
61 procedure_address); | |
62 | |
63 int procedure_size = iterator.GetNextUInt32(); | |
64 EXPECT_EQ(kProcedureSize, procedure_size); | |
65 } | |
66 | |
67 TEST_F(EhFrameWriterTest, SetOffset) { | |
68 static const int kOffset = 0x0badc0de; | |
69 | |
70 EhFrameWriter writer; | |
71 writer.SetBaseAddressOffset(kOffset); | |
72 writer.Finish(100); | |
73 | |
74 EhFrameIterator iterator(&writer); | |
75 iterator.SkipToFDEDirectives(); | |
76 | |
77 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kDefCfaOffset, | |
78 iterator.GetNextOpcode()); | |
79 EXPECT_EQ(kOffset, iterator.GetNextULEB128()); | |
80 } | |
81 | |
82 TEST_F(EhFrameWriterTest, IncreaseOffset) { | |
83 static const int kFirstOffset = 121; | |
84 static const int kSecondOffset = 16; | |
85 | |
86 EhFrameWriter writer; | |
87 writer.SetBaseAddressOffset(kFirstOffset); | |
88 writer.IncreaseBaseAddressOffset(kSecondOffset); | |
89 writer.Finish(100); | |
90 | |
91 EhFrameIterator iterator(&writer); | |
92 iterator.SkipToFDEDirectives(); | |
93 | |
94 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kDefCfaOffset, | |
95 iterator.GetNextOpcode()); | |
96 EXPECT_EQ(kFirstOffset, iterator.GetNextULEB128()); | |
97 | |
98 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kDefCfaOffset, | |
99 iterator.GetNextOpcode()); | |
100 EXPECT_EQ(kFirstOffset + kSecondOffset, iterator.GetNextULEB128()); | |
101 } | |
102 | |
103 TEST_F(EhFrameWriterTest, SetRegister) { | |
104 Register test_register = Register::from_code(kTestRegisterCode); | |
105 | |
106 EhFrameWriter writer; | |
107 writer.SetBaseAddressRegister(test_register); | |
108 writer.Finish(100); | |
109 | |
110 EhFrameIterator iterator(&writer); | |
111 iterator.SkipToFDEDirectives(); | |
112 | |
113 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kDefCfaRegister, | |
114 iterator.GetNextOpcode()); | |
115 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULEB128()); | |
116 } | |
117 | |
118 TEST_F(EhFrameWriterTest, SetRegisterAndOffset) { | |
119 Register test_register = Register::from_code(kTestRegisterCode); | |
120 static const int kOffset = 0x0badc0de; | |
121 | |
122 EhFrameWriter writer; | |
123 writer.SetBaseAddressRegisterAndOffset(test_register, kOffset); | |
124 writer.Finish(100); | |
125 | |
126 EhFrameIterator iterator(&writer); | |
127 iterator.SkipToFDEDirectives(); | |
128 | |
129 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kDefCfa, iterator.GetNextOpcode()); | |
130 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULEB128()); | |
131 EXPECT_EQ(kOffset, iterator.GetNextULEB128()); | |
132 } | |
133 | |
134 TEST_F(EhFrameWriterTest, PcOffsetEncoding6bit) { | |
135 static const int kOffset = 42; | |
136 | |
137 EhFrameWriter writer; | |
138 writer.AdvanceLocation(kOffset); | |
139 writer.Finish(100); | |
140 | |
141 EhFrameIterator iterator(&writer); | |
142 iterator.SkipToFDEDirectives(); | |
143 | |
144 EXPECT_EQ((1 << 6) | kOffset, iterator.GetNextByte()); | |
145 } | |
146 | |
147 TEST_F(EhFrameWriterTest, PcOffsetEncoding6bitDelta) { | |
148 static const int kFirstOffset = 42; | |
149 static const int kSecondOffset = 62; | |
150 | |
151 EhFrameWriter writer; | |
152 writer.AdvanceLocation(kFirstOffset); | |
153 writer.AdvanceLocation(kSecondOffset); | |
154 writer.Finish(100); | |
155 | |
156 EhFrameIterator iterator(&writer); | |
157 iterator.SkipToFDEDirectives(); | |
158 | |
159 EXPECT_EQ((1 << 6) | kFirstOffset, iterator.GetNextByte()); | |
160 EXPECT_EQ((1 << 6) | (kSecondOffset - kFirstOffset), iterator.GetNextByte()); | |
161 } | |
162 | |
163 TEST_F(EhFrameWriterTest, PcOffsetEncoding8bit) { | |
164 static const int kOffset = 0x42; | |
165 | |
166 EhFrameWriter writer; | |
167 writer.AdvanceLocation(kOffset); | |
168 writer.Finish(100); | |
169 | |
170 EhFrameIterator iterator(&writer); | |
171 iterator.SkipToFDEDirectives(); | |
172 | |
173 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc1, | |
174 iterator.GetNextOpcode()); | |
175 EXPECT_EQ(kOffset, iterator.GetNextByte()); | |
176 } | |
177 | |
178 TEST_F(EhFrameWriterTest, PcOffsetEncoding8bitDelta) { | |
179 static const int kFirstOffset = 0x10; | |
180 static const int kSecondOffset = 0x70; | |
181 static const int kThirdOffset = 0xb5; | |
182 | |
183 EhFrameWriter writer; | |
184 writer.AdvanceLocation(kFirstOffset); | |
185 writer.AdvanceLocation(kSecondOffset); | |
186 writer.AdvanceLocation(kThirdOffset); | |
187 writer.Finish(100); | |
188 | |
189 EhFrameIterator iterator(&writer); | |
190 iterator.SkipToFDEDirectives(); | |
191 | |
192 EXPECT_EQ((1 << 6) | kFirstOffset, iterator.GetNextByte()); | |
193 | |
194 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc1, | |
195 iterator.GetNextOpcode()); | |
196 EXPECT_EQ(kSecondOffset - kFirstOffset, iterator.GetNextByte()); | |
197 | |
198 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc1, | |
199 iterator.GetNextOpcode()); | |
200 EXPECT_EQ(kThirdOffset - kSecondOffset, iterator.GetNextByte()); | |
201 } | |
202 | |
203 TEST_F(EhFrameWriterTest, PcOffsetEncoding16bit) { | |
204 static const int kOffset = kMaxUInt8 + 42; | |
205 ASSERT_LT(kOffset, kMaxUInt16); | |
206 | |
207 EhFrameWriter writer; | |
208 writer.AdvanceLocation(kOffset); | |
209 writer.Finish(100); | |
210 | |
211 EhFrameIterator iterator(&writer); | |
212 iterator.SkipToFDEDirectives(); | |
213 | |
214 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc2, | |
215 iterator.GetNextOpcode()); | |
216 EXPECT_EQ(kOffset, iterator.GetNextUInt16()); | |
217 } | |
218 | |
219 TEST_F(EhFrameWriterTest, PcOffsetEncoding16bitDelta) { | |
220 static const int kFirstOffset = 0x41; | |
221 static const int kSecondOffset = kMaxUInt8 + 0x42; | |
222 | |
223 EhFrameWriter writer; | |
224 writer.AdvanceLocation(kFirstOffset); | |
225 writer.AdvanceLocation(kSecondOffset); | |
226 writer.Finish(100); | |
227 | |
228 EhFrameIterator iterator(&writer); | |
229 iterator.SkipToFDEDirectives(); | |
230 | |
231 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc1, | |
232 iterator.GetNextOpcode()); | |
233 EXPECT_EQ(kFirstOffset, iterator.GetNextByte()); | |
234 | |
235 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc2, | |
236 iterator.GetNextOpcode()); | |
237 EXPECT_EQ(kSecondOffset - kFirstOffset, iterator.GetNextUInt16()); | |
238 } | |
239 | |
240 TEST_F(EhFrameWriterTest, PcOffsetEncoding32bit) { | |
241 static const int kOffset = kMaxUInt16 + 42; | |
242 | |
243 EhFrameWriter writer; | |
244 writer.AdvanceLocation(kOffset); | |
245 writer.Finish(100); | |
246 | |
247 EhFrameIterator iterator(&writer); | |
248 iterator.SkipToFDEDirectives(); | |
249 | |
250 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc4, | |
251 iterator.GetNextOpcode()); | |
252 EXPECT_EQ(kOffset, iterator.GetNextUInt32()); | |
253 } | |
254 | |
255 TEST_F(EhFrameWriterTest, PcOffsetEncoding32bitDelta) { | |
256 static const int kFirstOffset = kMaxUInt16 + 0x42; | |
257 static const int kSecondOffset = kMaxUInt16 + 0x67; | |
258 | |
259 EhFrameWriter writer; | |
260 writer.AdvanceLocation(kFirstOffset); | |
261 writer.AdvanceLocation(kSecondOffset); | |
262 writer.Finish(100); | |
263 | |
264 EhFrameIterator iterator(&writer); | |
265 iterator.SkipToFDEDirectives(); | |
266 | |
267 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kAdvanceLoc4, | |
268 iterator.GetNextOpcode()); | |
269 EXPECT_EQ(kFirstOffset, iterator.GetNextUInt32()); | |
270 | |
271 EXPECT_EQ((1 << 6) | (kSecondOffset - kFirstOffset), iterator.GetNextByte()); | |
272 } | |
273 | |
274 TEST_F(EhFrameWriterTest, SaveRegisterPositiveOffset) { | |
275 Register test_register = Register::from_code(kTestRegisterCode); | |
276 static const int kOffset = 16; | |
277 | |
278 EhFrameWriter writer; | |
279 writer.RecordRegisterSavedToStack(test_register, kOffset); | |
280 writer.Finish(100); | |
281 | |
282 EhFrameIterator iterator(&writer); | |
283 iterator.SkipToFDEDirectives(); | |
284 | |
285 EXPECT_EQ((2 << 6) | kTestRegisterCode, iterator.GetNextByte()); | |
286 EXPECT_EQ(kOffset / std::abs(EhFrameWriter::kDataAlignmentFactor), | |
287 iterator.GetNextULEB128()); | |
288 } | |
289 | |
290 TEST_F(EhFrameWriterTest, SaveRegisterNegativeOffset) { | |
291 Register test_register = Register::from_code(kTestRegisterCode); | |
292 static const int kOffset = -12344; | |
293 ASSERT_EQ(kOffset % EhFrameWriter::kDataAlignmentFactor, 0); | |
294 | |
295 EhFrameWriter writer; | |
296 writer.RecordRegisterSavedToStack(test_register, kOffset); | |
297 writer.Finish(100); | |
298 | |
299 EhFrameIterator iterator(&writer); | |
300 iterator.SkipToFDEDirectives(); | |
301 | |
302 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kOffsetExtendedSf, | |
303 iterator.GetNextOpcode()); | |
304 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULEB128()); | |
305 EXPECT_EQ(kOffset / std::abs(EhFrameWriter::kDataAlignmentFactor), | |
306 iterator.GetNextSLEB128()); | |
307 } | |
308 | |
309 TEST_F(EhFrameWriterTest, SaveRegisterToTop) { | |
310 Register test_register = Register::from_code(kTestRegisterCode); | |
311 | |
312 EhFrameWriter writer; | |
313 int initial_base_offset = writer.base_offset(); | |
314 writer.RecordRegisterSavedToStack(test_register); | |
315 writer.Finish(100); | |
316 | |
317 EhFrameIterator iterator(&writer); | |
318 iterator.SkipToFDEDirectives(); | |
319 | |
320 EXPECT_EQ((2 << 6) | kTestRegisterCode, iterator.GetNextByte()); | |
321 EXPECT_EQ(initial_base_offset / std::abs(EhFrameWriter::kDataAlignmentFactor), | |
322 iterator.GetNextULEB128()); | |
323 } | |
324 | |
325 TEST_F(EhFrameWriterTest, RegisterIsValid) { | |
326 Register test_register = Register::from_code(kTestRegisterCode); | |
327 | |
328 EhFrameWriter writer; | |
329 writer.RecordRegisterIsValid(test_register); | |
330 writer.Finish(100); | |
331 | |
332 EhFrameIterator iterator(&writer); | |
333 iterator.SkipToFDEDirectives(); | |
334 | |
335 EXPECT_EQ(EhFrameWriter::DwarfOpcodes::kSameValue, iterator.GetNextOpcode()); | |
336 EXPECT_EQ(kTestRegisterCode, iterator.GetNextULEB128()); | |
337 } | |
338 | |
339 TEST_F(EhFrameWriterTest, RegisterFollowsInitialRule) { | |
340 Register test_register = Register::from_code(kTestRegisterCode); | |
341 | |
342 EhFrameWriter writer; | |
343 writer.RecordRegisterFollowsInitialRule(test_register); | |
344 writer.Finish(100); | |
345 | |
346 EhFrameIterator iterator(&writer); | |
347 iterator.SkipToFDEDirectives(); | |
348 | |
349 EXPECT_EQ((3 << 6) | kTestRegisterCode, iterator.GetNextByte()); | |
350 } | |
351 | |
352 #endif | |
OLD | NEW |