system/core
修订版 | 9f6f6f071d89c70606792ad02b68de80d93921b7 (tree) |
---|---|
时间 | 2019-03-30 12:10:47 |
作者 | Christopher Ferris <cferris@goog...> |
Commiter | android-build-merger |
Merge "Remove sequential search from DwarfEhFrameWithHdr." am: cab97bc6eb
am: 3b6c4210f5
Change-Id: Iff2f6320f9dcc91bc262290bebdc203e0683c778
@@ -61,6 +61,14 @@ bool DwarfEhFrameWithHdr<AddressType>::Init(uint64_t offset, uint64_t size, uint | ||
61 | 61 | table_encoding_ = data[3]; |
62 | 62 | table_entry_size_ = memory_.template GetEncodedSize<AddressType>(table_encoding_); |
63 | 63 | |
64 | + // If we can't perform a binary search on the entries, it's not worth | |
65 | + // using this object. The calling code will fall back to the DwarfEhFrame | |
66 | + // object in this case. | |
67 | + if (table_entry_size_ == 0) { | |
68 | + last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; | |
69 | + return false; | |
70 | + } | |
71 | + | |
64 | 72 | memory_.set_pc_offset(memory_.cur_offset()); |
65 | 73 | if (!memory_.template ReadEncodedValue<AddressType>(ptr_encoding_, &ptr_offset_)) { |
66 | 74 | last_error_.code = DWARF_ERROR_MEMORY_INVALID; |
@@ -137,13 +145,13 @@ DwarfEhFrameWithHdr<AddressType>::GetFdeInfoFromIndex(size_t index) { | ||
137 | 145 | } |
138 | 146 | |
139 | 147 | template <typename AddressType> |
140 | -bool DwarfEhFrameWithHdr<AddressType>::GetFdeOffsetBinary(uint64_t pc, uint64_t* fde_offset, | |
141 | - uint64_t total_entries) { | |
142 | - CHECK(fde_count_ > 0); | |
143 | - CHECK(total_entries <= fde_count_); | |
148 | +bool DwarfEhFrameWithHdr<AddressType>::GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) { | |
149 | + if (fde_count_ == 0) { | |
150 | + return false; | |
151 | + } | |
144 | 152 | |
145 | 153 | size_t first = 0; |
146 | - size_t last = total_entries; | |
154 | + size_t last = fde_count_; | |
147 | 155 | while (first < last) { |
148 | 156 | size_t current = (first + last) / 2; |
149 | 157 | const FdeInfo* info = GetFdeInfoFromIndex(current); |
@@ -172,87 +180,6 @@ bool DwarfEhFrameWithHdr<AddressType>::GetFdeOffsetBinary(uint64_t pc, uint64_t* | ||
172 | 180 | } |
173 | 181 | |
174 | 182 | template <typename AddressType> |
175 | -bool DwarfEhFrameWithHdr<AddressType>::GetFdeOffsetSequential(uint64_t pc, uint64_t* fde_offset) { | |
176 | - CHECK(fde_count_ != 0); | |
177 | - last_error_.code = DWARF_ERROR_NONE; | |
178 | - last_error_.address = 0; | |
179 | - | |
180 | - // We can do a binary search if the pc is in the range of the elements | |
181 | - // that have already been cached. | |
182 | - if (!fde_info_.empty()) { | |
183 | - const FdeInfo* info = &fde_info_[fde_info_.size() - 1]; | |
184 | - if (pc >= info->pc) { | |
185 | - *fde_offset = info->offset; | |
186 | - return true; | |
187 | - } | |
188 | - if (pc < info->pc) { | |
189 | - return GetFdeOffsetBinary(pc, fde_offset, fde_info_.size()); | |
190 | - } | |
191 | - } | |
192 | - | |
193 | - if (cur_entries_offset_ == 0) { | |
194 | - // All entries read, or error encountered. | |
195 | - return false; | |
196 | - } | |
197 | - | |
198 | - memory_.set_data_offset(entries_data_offset_); | |
199 | - memory_.set_cur_offset(cur_entries_offset_); | |
200 | - memory_.set_pc_offset(0); | |
201 | - cur_entries_offset_ = 0; | |
202 | - | |
203 | - FdeInfo* prev_info = nullptr; | |
204 | - for (size_t current = fde_info_.size(); | |
205 | - current < fde_count_ && memory_.cur_offset() < entries_end_; current++) { | |
206 | - FdeInfo* info = &fde_info_[current]; | |
207 | - uint64_t value; | |
208 | - if (!memory_.template ReadEncodedValue<AddressType>(table_encoding_, &value) || | |
209 | - !memory_.template ReadEncodedValue<AddressType>(table_encoding_, &info->offset)) { | |
210 | - fde_info_.erase(current); | |
211 | - last_error_.code = DWARF_ERROR_MEMORY_INVALID; | |
212 | - last_error_.address = memory_.cur_offset(); | |
213 | - return false; | |
214 | - } | |
215 | - | |
216 | - // Relative encodings require adding in the load bias. | |
217 | - if (IsEncodingRelative(table_encoding_)) { | |
218 | - value += load_bias_; | |
219 | - } | |
220 | - info->pc = value; | |
221 | - | |
222 | - if (pc < info->pc) { | |
223 | - if (prev_info == nullptr) { | |
224 | - return false; | |
225 | - } | |
226 | - cur_entries_offset_ = memory_.cur_offset(); | |
227 | - *fde_offset = prev_info->offset; | |
228 | - return true; | |
229 | - } | |
230 | - prev_info = info; | |
231 | - } | |
232 | - | |
233 | - if (fde_count_ == fde_info_.size() && pc >= prev_info->pc) { | |
234 | - *fde_offset = prev_info->offset; | |
235 | - return true; | |
236 | - } | |
237 | - return false; | |
238 | -} | |
239 | - | |
240 | -template <typename AddressType> | |
241 | -bool DwarfEhFrameWithHdr<AddressType>::GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) { | |
242 | - if (fde_count_ == 0) { | |
243 | - return false; | |
244 | - } | |
245 | - | |
246 | - if (table_entry_size_ > 0) { | |
247 | - // Do a binary search since the size of each table entry is fixed. | |
248 | - return GetFdeOffsetBinary(pc, fde_offset, fde_count_); | |
249 | - } else { | |
250 | - // Do a sequential search since each table entry size is variable. | |
251 | - return GetFdeOffsetSequential(pc, fde_offset); | |
252 | - } | |
253 | -} | |
254 | - | |
255 | -template <typename AddressType> | |
256 | 183 | void DwarfEhFrameWithHdr<AddressType>::GetFdes(std::vector<const DwarfFde*>* fdes) { |
257 | 184 | for (size_t i = 0; i < fde_count_; i++) { |
258 | 185 | const FdeInfo* info = GetFdeInfoFromIndex(i); |
@@ -69,10 +69,6 @@ class DwarfEhFrameWithHdr : public DwarfSectionImpl<AddressType> { | ||
69 | 69 | |
70 | 70 | const FdeInfo* GetFdeInfoFromIndex(size_t index); |
71 | 71 | |
72 | - bool GetFdeOffsetSequential(uint64_t pc, uint64_t* fde_offset); | |
73 | - | |
74 | - bool GetFdeOffsetBinary(uint64_t pc, uint64_t* fde_offset, uint64_t total_entries); | |
75 | - | |
76 | 72 | void GetFdes(std::vector<const DwarfFde*>* fdes) override; |
77 | 73 | |
78 | 74 | protected: |
@@ -95,6 +95,13 @@ TYPED_TEST_P(DwarfEhFrameWithHdrTest, Init) { | ||
95 | 95 | EXPECT_EQ(0x1000U, this->eh_frame_->TestGetEntriesDataOffset()); |
96 | 96 | EXPECT_EQ(0x100aU, this->eh_frame_->TestGetCurEntriesOffset()); |
97 | 97 | |
98 | + // Verify a zero table entry size fails to init. | |
99 | + this->memory_.SetData8(0x1003, 0x1); | |
100 | + ASSERT_FALSE(this->eh_frame_->Init(0x1000, 0x100, 0)); | |
101 | + ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->eh_frame_->LastErrorCode()); | |
102 | + // Reset the value back to the original. | |
103 | + this->memory_.SetData8(0x1003, DW_EH_PE_sdata4); | |
104 | + | |
98 | 105 | // Verify a zero fde count fails to init. |
99 | 106 | this->memory_.SetData32(0x1006, 0); |
100 | 107 | ASSERT_FALSE(this->eh_frame_->Init(0x1000, 0x100, 0)); |
@@ -276,9 +283,8 @@ TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeInfoFromIndex_cached) { | ||
276 | 283 | EXPECT_EQ(0x500U, info->offset); |
277 | 284 | } |
278 | 285 | |
279 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetBinary_verify) { | |
286 | +TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_verify) { | |
280 | 287 | this->eh_frame_->TestSetTableEntrySize(0x10); |
281 | - this->eh_frame_->TestSetFdeCount(10); | |
282 | 288 | |
283 | 289 | typename DwarfEhFrameWithHdr<TypeParam>::FdeInfo info; |
284 | 290 | for (size_t i = 0; i < 10; i++) { |
@@ -288,105 +294,42 @@ TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetBinary_verify) { | ||
288 | 294 | } |
289 | 295 | |
290 | 296 | uint64_t fde_offset; |
291 | - EXPECT_FALSE(this->eh_frame_->GetFdeOffsetBinary(0x100, &fde_offset, 10)); | |
297 | + this->eh_frame_->TestSetFdeCount(10); | |
298 | + EXPECT_FALSE(this->eh_frame_->GetFdeOffsetFromPc(0x100, &fde_offset)); | |
292 | 299 | // Not an error, just not found. |
293 | 300 | ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode()); |
294 | 301 | // Even number of elements. |
295 | 302 | for (size_t i = 0; i < 10; i++) { |
303 | + SCOPED_TRACE(testing::Message() << "Failed at index " << i); | |
296 | 304 | TypeParam pc = 0x1000 * (i + 1); |
297 | - EXPECT_TRUE(this->eh_frame_->GetFdeOffsetBinary(pc, &fde_offset, 10)) << "Failed at index " << i; | |
298 | - EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; | |
299 | - EXPECT_TRUE(this->eh_frame_->GetFdeOffsetBinary(pc + 1, &fde_offset, 10)) | |
300 | - << "Failed at index " << i; | |
301 | - EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; | |
302 | - EXPECT_TRUE(this->eh_frame_->GetFdeOffsetBinary(pc + 0xfff, &fde_offset, 10)) | |
303 | - << "Failed at index " << i; | |
304 | - EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; | |
305 | + EXPECT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc, &fde_offset)); | |
306 | + EXPECT_EQ(0x5000 + i * 0x20, fde_offset); | |
307 | + EXPECT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)); | |
308 | + EXPECT_EQ(0x5000 + i * 0x20, fde_offset); | |
309 | + EXPECT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset)); | |
310 | + EXPECT_EQ(0x5000 + i * 0x20, fde_offset); | |
305 | 311 | } |
312 | + | |
306 | 313 | // Odd number of elements. |
314 | + this->eh_frame_->TestSetFdeCount(9); | |
307 | 315 | for (size_t i = 0; i < 9; i++) { |
316 | + SCOPED_TRACE(testing::Message() << "Failed at index " << i); | |
308 | 317 | TypeParam pc = 0x1000 * (i + 1); |
309 | - EXPECT_TRUE(this->eh_frame_->GetFdeOffsetBinary(pc, &fde_offset, 9)) << "Failed at index " << i; | |
310 | - EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; | |
311 | - EXPECT_TRUE(this->eh_frame_->GetFdeOffsetBinary(pc + 1, &fde_offset, 9)) | |
312 | - << "Failed at index " << i; | |
313 | - EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; | |
314 | - EXPECT_TRUE(this->eh_frame_->GetFdeOffsetBinary(pc + 0xfff, &fde_offset, 9)) | |
315 | - << "Failed at index " << i; | |
316 | - EXPECT_EQ(0x5000 + i * 0x20, fde_offset) << "Failed at index " << i; | |
318 | + EXPECT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc, &fde_offset)); | |
319 | + EXPECT_EQ(0x5000 + i * 0x20, fde_offset); | |
320 | + EXPECT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 1, &fde_offset)); | |
321 | + EXPECT_EQ(0x5000 + i * 0x20, fde_offset); | |
322 | + EXPECT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(pc + 0xfff, &fde_offset)); | |
323 | + EXPECT_EQ(0x5000 + i * 0x20, fde_offset); | |
317 | 324 | } |
318 | 325 | } |
319 | 326 | |
320 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetBinary_index_fail) { | |
327 | +TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_index_fail) { | |
321 | 328 | this->eh_frame_->TestSetTableEntrySize(0x10); |
322 | 329 | this->eh_frame_->TestSetFdeCount(10); |
323 | 330 | |
324 | 331 | uint64_t fde_offset; |
325 | - EXPECT_FALSE(this->eh_frame_->GetFdeOffsetBinary(0x1000, &fde_offset, 10)); | |
326 | -} | |
327 | - | |
328 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetSequential) { | |
329 | - this->eh_frame_->TestSetFdeCount(10); | |
330 | - this->eh_frame_->TestSetEntriesDataOffset(0x100); | |
331 | - this->eh_frame_->TestSetEntriesEnd(0x2000); | |
332 | - this->eh_frame_->TestSetTableEncoding(DW_EH_PE_udata4); | |
333 | - | |
334 | - this->memory_.SetData32(0x1040, 0x340); | |
335 | - this->memory_.SetData32(0x1044, 0x500); | |
336 | - | |
337 | - this->memory_.SetData32(0x1048, 0x440); | |
338 | - this->memory_.SetData32(0x104c, 0x600); | |
339 | - | |
340 | - // Verify that if entries is zero, that it fails. | |
341 | - uint64_t fde_offset; | |
342 | - ASSERT_FALSE(this->eh_frame_->GetFdeOffsetSequential(0x344, &fde_offset)); | |
343 | - this->eh_frame_->TestSetCurEntriesOffset(0x1040); | |
344 | - | |
345 | - ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x344, &fde_offset)); | |
346 | - EXPECT_EQ(0x500U, fde_offset); | |
347 | - | |
348 | - ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x444, &fde_offset)); | |
349 | - EXPECT_EQ(0x600U, fde_offset); | |
350 | - | |
351 | - // Expect that the data is cached so no more memory reads will occur. | |
352 | - this->memory_.Clear(); | |
353 | - ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x444, &fde_offset)); | |
354 | - EXPECT_EQ(0x600U, fde_offset); | |
355 | -} | |
356 | - | |
357 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetSequential_last_element) { | |
358 | - this->eh_frame_->TestSetFdeCount(2); | |
359 | - this->eh_frame_->TestSetEntriesDataOffset(0x100); | |
360 | - this->eh_frame_->TestSetEntriesEnd(0x2000); | |
361 | - this->eh_frame_->TestSetTableEncoding(DW_EH_PE_udata4); | |
362 | - this->eh_frame_->TestSetCurEntriesOffset(0x1040); | |
363 | - | |
364 | - this->memory_.SetData32(0x1040, 0x340); | |
365 | - this->memory_.SetData32(0x1044, 0x500); | |
366 | - | |
367 | - this->memory_.SetData32(0x1048, 0x440); | |
368 | - this->memory_.SetData32(0x104c, 0x600); | |
369 | - | |
370 | - uint64_t fde_offset; | |
371 | - ASSERT_TRUE(this->eh_frame_->GetFdeOffsetSequential(0x540, &fde_offset)); | |
372 | - EXPECT_EQ(0x600U, fde_offset); | |
373 | -} | |
374 | - | |
375 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetSequential_end_check) { | |
376 | - this->eh_frame_->TestSetFdeCount(2); | |
377 | - this->eh_frame_->TestSetEntriesDataOffset(0x100); | |
378 | - this->eh_frame_->TestSetEntriesEnd(0x1048); | |
379 | - this->eh_frame_->TestSetTableEncoding(DW_EH_PE_udata4); | |
380 | - | |
381 | - this->memory_.SetData32(0x1040, 0x340); | |
382 | - this->memory_.SetData32(0x1044, 0x500); | |
383 | - | |
384 | - this->memory_.SetData32(0x1048, 0x440); | |
385 | - this->memory_.SetData32(0x104c, 0x600); | |
386 | - | |
387 | - uint64_t fde_offset; | |
388 | - ASSERT_FALSE(this->eh_frame_->GetFdeOffsetSequential(0x540, &fde_offset)); | |
389 | - ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode()); | |
332 | + EXPECT_FALSE(this->eh_frame_->GetFdeOffsetFromPc(0x1000, &fde_offset)); | |
390 | 333 | } |
391 | 334 | |
392 | 335 | TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_fail_fde_count) { |
@@ -397,7 +340,7 @@ TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_fail_fde_count) { | ||
397 | 340 | ASSERT_EQ(DWARF_ERROR_NONE, this->eh_frame_->LastErrorCode()); |
398 | 341 | } |
399 | 342 | |
400 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_binary_search) { | |
343 | +TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_search) { | |
401 | 344 | this->eh_frame_->TestSetTableEntrySize(16); |
402 | 345 | this->eh_frame_->TestSetFdeCount(10); |
403 | 346 |
@@ -417,26 +360,6 @@ TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_binary_search) { | ||
417 | 360 | EXPECT_EQ(0x10700U, fde_offset); |
418 | 361 | } |
419 | 362 | |
420 | -TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeOffsetFromPc_sequential_search) { | |
421 | - this->eh_frame_->TestSetFdeCount(10); | |
422 | - this->eh_frame_->TestSetTableEntrySize(0); | |
423 | - | |
424 | - typename DwarfEhFrameWithHdr<TypeParam>::FdeInfo info; | |
425 | - info.pc = 0x50; | |
426 | - info.offset = 0x10000; | |
427 | - this->eh_frame_->TestSetFdeInfo(0, info); | |
428 | - info.pc = 0x150; | |
429 | - info.offset = 0x10100; | |
430 | - this->eh_frame_->TestSetFdeInfo(1, info); | |
431 | - info.pc = 0x250; | |
432 | - info.offset = 0x10200; | |
433 | - this->eh_frame_->TestSetFdeInfo(2, info); | |
434 | - | |
435 | - uint64_t fde_offset; | |
436 | - ASSERT_TRUE(this->eh_frame_->GetFdeOffsetFromPc(0x200, &fde_offset)); | |
437 | - EXPECT_EQ(0x10100U, fde_offset); | |
438 | -} | |
439 | - | |
440 | 363 | TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetCieFde32) { |
441 | 364 | // CIE 32 information. |
442 | 365 | this->memory_.SetData32(0xf000, 0x100); |
@@ -526,10 +449,8 @@ TYPED_TEST_P(DwarfEhFrameWithHdrTest, GetFdeFromPc_fde_not_found) { | ||
526 | 449 | REGISTER_TYPED_TEST_CASE_P(DwarfEhFrameWithHdrTest, Init, Init_non_zero_load_bias, GetFdes, |
527 | 450 | GetFdeInfoFromIndex_expect_cache_fail, GetFdeInfoFromIndex_read_pcrel, |
528 | 451 | GetFdeInfoFromIndex_read_datarel, GetFdeInfoFromIndex_cached, |
529 | - GetFdeOffsetBinary_verify, GetFdeOffsetBinary_index_fail, | |
530 | - GetFdeOffsetSequential, GetFdeOffsetSequential_last_element, | |
531 | - GetFdeOffsetSequential_end_check, GetFdeOffsetFromPc_fail_fde_count, | |
532 | - GetFdeOffsetFromPc_binary_search, GetFdeOffsetFromPc_sequential_search, | |
452 | + GetFdeOffsetFromPc_verify, GetFdeOffsetFromPc_index_fail, | |
453 | + GetFdeOffsetFromPc_fail_fde_count, GetFdeOffsetFromPc_search, | |
533 | 454 | GetCieFde32, GetCieFde64, GetFdeFromPc_fde_not_found); |
534 | 455 | |
535 | 456 | typedef ::testing::Types<uint32_t, uint64_t> DwarfEhFrameWithHdrTestTypes; |