Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: obsolete/breakpad/common/dwarf_cu_to_module_unittest.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2010 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31
32 // dwarf_cu_to_module.cc: Unit tests for google_breakpad::DwarfCUToModule.
33
34 #include <vector>
35
36 #include "breakpad_googletest_includes.h"
37 #include "common/dwarf_cu_to_module.h"
38
39 using std::vector;
40
41 using dwarf2reader::AttributeList;
42 using dwarf2reader::DIEHandler;
43 using dwarf2reader::DwarfTag;
44 using dwarf2reader::DwarfAttribute;
45 using dwarf2reader::DwarfForm;
46 using dwarf2reader::DwarfInline;
47 using dwarf2reader::RootDIEHandler;
48 using google_breakpad::DwarfCUToModule;
49 using google_breakpad::Module;
50
51 using ::testing::_;
52 using ::testing::AtMost;
53 using ::testing::Invoke;
54 using ::testing::Return;
55 using ::testing::Test;
56 using ::testing::TestWithParam;
57 using ::testing::Values;
58 using ::testing::ValuesIn;
59
60 // Mock classes.
61
62 class MockLineToModuleFunctor: public DwarfCUToModule::LineToModuleFunctor {
63 public:
64 MOCK_METHOD4(mock_apply, void(const char *program, uint64 length,
65 Module *module, vector<Module::Line> *lines));
66 void operator()(const char *program, uint64 length,
67 Module *module, vector<Module::Line> *lines) {
68 mock_apply(program, length, module, lines);
69 }
70 };
71
72 class MockWarningReporter: public DwarfCUToModule::WarningReporter {
73 public:
74 MockWarningReporter(const string &filename, uint64 cu_offset)
75 : DwarfCUToModule::WarningReporter(filename, cu_offset) { }
76 MOCK_METHOD1(SetCUName, void(const string &name));
77 MOCK_METHOD2(UnknownSpecification, void(uint64 offset, uint64 target));
78 MOCK_METHOD2(UnknownAbstractOrigin, void(uint64 offset, uint64 target));
79 MOCK_METHOD1(MissingSection, void(const string &section_name));
80 MOCK_METHOD1(BadLineInfoOffset, void(uint64 offset));
81 MOCK_METHOD1(UncoveredFunction, void(const Module::Function &function));
82 MOCK_METHOD1(UncoveredLine, void(const Module::Line &line));
83 };
84
85 // A fixture class including all the objects needed to handle a
86 // compilation unit, and their entourage. It includes member functions
87 // for doing common kinds of setup and tests.
88 class CUFixtureBase {
89 public:
90
91 // If we have:
92 //
93 // vector<Module::Line> lines;
94 // AppendLinesFunctor appender(lines);
95 //
96 // then doing:
97 //
98 // appender(line_program, length, module, line_vector);
99 //
100 // will append lines to the end of line_vector. We can use this with
101 // MockLineToModuleFunctor like this:
102 //
103 // MockLineToModuleFunctor l2m;
104 // EXPECT_CALL(l2m, mock_apply(_,_,_,_))
105 // .WillOnce(DoAll(Invoke(appender), Return()));
106 //
107 // in which case calling l2m with some line vector will append lines.
108 class AppendLinesFunctor {
109 public:
110 AppendLinesFunctor(const vector<Module::Line> *lines) : lines_(lines) { }
111 void operator()(const char *program, uint64 length,
112 Module *module, vector<Module::Line> *lines) {
113 lines->insert(lines->end(), lines_->begin(), lines_->end());
114 }
115 private:
116 const vector<Module::Line> *lines_;
117 };
118
119 CUFixtureBase()
120 : module_("module-name", "module-os", "module-arch", "module-id"),
121 file_context_("dwarf-filename", &module_),
122 language_(dwarf2reader::DW_LANG_none),
123 language_signed_(false),
124 appender_(&lines_),
125 reporter_("dwarf-filename", 0xcf8f9bb6443d29b5LL),
126 root_handler_(&file_context_, &line_reader_, &reporter_),
127 functions_filled_(false) {
128 // By default, expect no warnings to be reported, and expect the
129 // compilation unit's name to be provided. The test can override
130 // these expectations.
131 EXPECT_CALL(reporter_, SetCUName("compilation-unit-name")).Times(1);
132 EXPECT_CALL(reporter_, UnknownSpecification(_, _)).Times(0);
133 EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, _)).Times(0);
134 EXPECT_CALL(reporter_, MissingSection(_)).Times(0);
135 EXPECT_CALL(reporter_, BadLineInfoOffset(_)).Times(0);
136 EXPECT_CALL(reporter_, UncoveredFunction(_)).Times(0);
137 EXPECT_CALL(reporter_, UncoveredLine(_)).Times(0);
138
139 // By default, expect the line program reader not to be invoked. We
140 // may override this in StartCU.
141 EXPECT_CALL(line_reader_, mock_apply(_,_,_,_)).Times(0);
142
143 // The handler will consult this section map to decide what to
144 // pass to our line reader.
145 file_context_.section_map[".debug_line"] = std::make_pair(dummy_line_program _,
146 dummy_line_size_);
147 }
148
149 // Add a line with the given address, size, filename, and line
150 // number to the end of the statement list the handler will receive
151 // when it invokes its LineToModuleFunctor. Call this before calling
152 // StartCU.
153 void PushLine(Module::Address address, Module::Address size,
154 const string &filename, int line_number);
155
156 // Use LANGUAGE for the compilation unit. More precisely, arrange
157 // for StartCU to pass the compilation unit's root DIE a
158 // DW_AT_language attribute whose value is LANGUAGE.
159 void SetLanguage(dwarf2reader::DwarfLanguage language) {
160 language_ = language;
161 }
162
163 // If SIGNED true, have StartCU report DW_AT_language as a signed
164 // attribute; if false, have it report it as unsigned.
165 void SetLanguageSigned(bool is_signed) { language_signed_ = is_signed; }
166
167 // Call the handler this.root_handler_'s StartCompilationUnit and
168 // StartRootDIE member functions, passing it appropriate attributes as
169 // determined by prior calls to PushLine and SetLanguage. Leave
170 // this.root_handler_ ready to hear about children: call
171 // this.root_handler_.EndAttributes, but not this.root_handler_.Finish.
172 void StartCU();
173
174 // Add some strange attributes/form pairs to the end of ATTRS.
175 void PushBackStrangeAttributes(dwarf2reader::AttributeList *attrs);
176
177 // Have HANDLER process some strange attribute/form/value triples.
178 // These will match those promised by PushBackStrangeAttributes.
179 void ProcessStrangeAttributes(dwarf2reader::DIEHandler *handler);
180
181 // Start a child DIE of PARENT with the given tag and name. Leave
182 // the handler ready to hear about children: call EndAttributes, but
183 // not Finish.
184 DIEHandler *StartNamedDIE(DIEHandler *parent, DwarfTag tag,
185 const string &name);
186
187 // Start a child DIE of PARENT with the given tag and a
188 // DW_AT_specification attribute whose value is SPECIFICATION. Leave
189 // the handler ready to hear about children: call EndAttributes, but
190 // not Finish. If NAME is non-zero, use it as the DW_AT_name
191 // attribute.
192 DIEHandler *StartSpecifiedDIE(DIEHandler *parent, DwarfTag tag,
193 uint64 offset, const char *name = NULL);
194
195 // Define a function as a child of PARENT with the given name,
196 // address, and size. Call EndAttributes and Finish; one cannot
197 // define children of the defined function's DIE.
198 void DefineFunction(DIEHandler *parent, const string &name,
199 Module::Address address, Module::Address size);
200
201 // Create a declaration DIE as a child of PARENT with the given
202 // offset, tag and name. If NAME is the empty string, don't provide
203 // a DW_AT_name attribute. Call EndAttributes and Finish.
204 void DeclarationDIE(DIEHandler *parent, uint64 offset,
205 DwarfTag tag, const string &name);
206
207 // Create a definition DIE as a child of PARENT with the given tag
208 // that refers to the declaration DIE at offset SPECIFICATION as its
209 // specification. If NAME is non-empty, pass it as the DW_AT_name
210 // attribute. If SIZE is non-zero, record ADDRESS and SIZE as
211 // low_pc/high_pc attributes.
212 void DefinitionDIE(DIEHandler *parent, DwarfTag tag,
213 uint64 specification, const string &name,
214 Module::Address address = 0, Module::Address size = 0);
215
216 // Create an inline DW_TAG_subprogram DIE as a child of PARENT. If
217 // SPECIFICATION is non-zero, then the DIE refers to the declaration DIE at
218 // offset SPECIFICATION as its specification. If Name is non-empty, pass it
219 // as the DW_AT_name attribute.
220 void AbstractInstanceDIE(DIEHandler *parent, uint64 offset,
221 DwarfInline type, uint64 specification,
222 const string &name,
223 DwarfForm form = dwarf2reader::DW_FORM_data1);
224
225 // Create a DW_TAG_subprogram DIE as a child of PARENT that refers to
226 // ORIGIN in its DW_AT_abstract_origin attribute. If NAME is the empty
227 // string, don't provide a DW_AT_name attribute.
228 void DefineInlineInstanceDIE(DIEHandler *parent, const string &name,
229 uint64 origin, Module::Address address,
230 Module::Address size);
231
232 // The following Test* functions should be called after calling
233 // this.root_handler_.Finish. After that point, no further calls
234 // should be made on the handler.
235
236 // Test that the number of functions defined in the module this.module_ is
237 // equal to EXPECTED.
238 void TestFunctionCount(size_t expected);
239
240 // Test that the I'th function (ordered by address) in the module
241 // this.module_ has the given name, address, and size, and that its
242 // parameter size is zero.
243 void TestFunction(int i, const string &name,
244 Module::Address address, Module::Address size);
245
246 // Test that the number of source lines owned by the I'th function
247 // in the module this.module_ is equal to EXPECTED.
248 void TestLineCount(int i, size_t expected);
249
250 // Test that the J'th line (ordered by address) of the I'th function
251 // (again, by address) has the given address, size, filename, and
252 // line number.
253 void TestLine(int i, int j, Module::Address address, Module::Address size,
254 const string &filename, int number);
255
256 // Actual objects under test.
257 Module module_;
258 DwarfCUToModule::FileContext file_context_;
259
260 // If this is not DW_LANG_none, we'll pass it as a DW_AT_language
261 // attribute to the compilation unit. This defaults to DW_LANG_none.
262 dwarf2reader::DwarfLanguage language_;
263
264 // If this is true, report DW_AT_language as a signed value; if false,
265 // report it as an unsigned value.
266 bool language_signed_;
267
268 // If this is not empty, we'll give the CU a DW_AT_stmt_list
269 // attribute that, when passed to line_reader_, adds these lines to the
270 // provided lines array.
271 vector<Module::Line> lines_;
272
273 // Mock line program reader.
274 MockLineToModuleFunctor line_reader_;
275 AppendLinesFunctor appender_;
276 static const char dummy_line_program_[];
277 static const size_t dummy_line_size_;
278
279 MockWarningReporter reporter_;
280 DwarfCUToModule root_handler_;
281
282 private:
283 // Fill functions_, if we haven't already.
284 void FillFunctions();
285
286 // If functions_filled_ is true, this is a table of functions we've
287 // extracted from module_, sorted by address.
288 vector<Module::Function *> functions_;
289 // True if we have filled the above vector with this.module_'s function list.
290 bool functions_filled_;
291 };
292
293 const char CUFixtureBase::dummy_line_program_[] = "lots of fun data";
294 const size_t CUFixtureBase::dummy_line_size_ =
295 sizeof (CUFixtureBase::dummy_line_program_);
296
297 void CUFixtureBase::PushLine(Module::Address address, Module::Address size,
298 const string &filename, int line_number) {
299 Module::Line l;
300 l.address = address;
301 l.size = size;
302 l.file = module_.FindFile(filename);
303 l.number = line_number;
304 lines_.push_back(l);
305 }
306
307 void CUFixtureBase::StartCU() {
308 // If we have lines, make the line reader expect to be invoked at
309 // most once. (Hey, if the handler can pass its tests without
310 // bothering to read the line number data, that's great.)
311 // Have it add the lines passed to PushLine. Otherwise, leave the
312 // initial expectation (no calls) in force.
313 if (!lines_.empty())
314 EXPECT_CALL(line_reader_,
315 mock_apply(&dummy_line_program_[0], dummy_line_size_,
316 &module_, _))
317 .Times(AtMost(1))
318 .WillOnce(DoAll(Invoke(appender_), Return()));
319
320 ASSERT_TRUE(root_handler_
321 .StartCompilationUnit(0x51182ec307610b51ULL, 0x81, 0x44,
322 0x4241b4f33720dd5cULL, 3));
323 {
324 dwarf2reader::AttributeList attrs;
325 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
326 dwarf2reader::DW_FORM_strp));
327 if (!lines_.empty())
328 attrs.push_back(make_pair(dwarf2reader::DW_AT_stmt_list,
329 dwarf2reader::DW_FORM_ref4));
330 if (language_ != dwarf2reader::DW_LANG_none)
331 attrs.push_back(make_pair(dwarf2reader::DW_AT_language,
332 language_signed_
333 ? dwarf2reader::DW_FORM_sdata
334 : dwarf2reader::DW_FORM_udata));
335 ASSERT_TRUE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL,
336 dwarf2reader::DW_TAG_compile_unit,
337 attrs));
338 }
339 root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
340 dwarf2reader::DW_FORM_strp,
341 "compilation-unit-name");
342 if (!lines_.empty())
343 root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list,
344 dwarf2reader::DW_FORM_ref4,
345 0);
346 if (language_ != dwarf2reader::DW_LANG_none) {
347 if (language_signed_)
348 root_handler_.ProcessAttributeSigned(dwarf2reader::DW_AT_language,
349 dwarf2reader::DW_FORM_sdata,
350 language_);
351 else
352 root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_language,
353 dwarf2reader::DW_FORM_udata,
354 language_);
355 }
356 ASSERT_TRUE(root_handler_.EndAttributes());
357 }
358
359 void CUFixtureBase::PushBackStrangeAttributes(
360 dwarf2reader::AttributeList *attrs) {
361 attrs->push_back(make_pair((DwarfAttribute) 0xf560dead,
362 (DwarfForm) 0x4106e4db));
363 attrs->push_back(make_pair((DwarfAttribute) 0x85380095,
364 (DwarfForm) 0x0f16fe87));
365 attrs->push_back(make_pair((DwarfAttribute) 0xf7f7480f,
366 (DwarfForm) 0x829e038a));
367 attrs->push_back(make_pair((DwarfAttribute) 0xa55ffb51,
368 (DwarfForm) 0x2f43b041));
369 attrs->push_back(make_pair((DwarfAttribute) 0x2fde304a,
370 (DwarfForm) 0x895ffa23));
371 }
372
373 void CUFixtureBase::ProcessStrangeAttributes(
374 dwarf2reader::DIEHandler *handler) {
375 handler->ProcessAttributeUnsigned((DwarfAttribute) 0xf560dead,
376 (DwarfForm) 0x4106e4db,
377 0xa592571997facda1ULL);
378 handler->ProcessAttributeSigned((DwarfAttribute) 0x85380095,
379 (DwarfForm) 0x0f16fe87,
380 0x12602a4e3bf1f446LL);
381 handler->ProcessAttributeReference((DwarfAttribute) 0xf7f7480f,
382 (DwarfForm) 0x829e038a,
383 0x50fddef44734fdecULL);
384 static const char buffer[10] = "frobynode";
385 handler->ProcessAttributeBuffer((DwarfAttribute) 0xa55ffb51,
386 (DwarfForm) 0x2f43b041,
387 buffer, sizeof(buffer));
388 handler->ProcessAttributeString((DwarfAttribute) 0x2f43b041,
389 (DwarfForm) 0x895ffa23,
390 "strange string");
391 }
392
393 DIEHandler *CUFixtureBase::StartNamedDIE(DIEHandler *parent,
394 DwarfTag tag,
395 const string &name) {
396 dwarf2reader::AttributeList attrs;
397 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
398 dwarf2reader::DW_FORM_strp));
399 PushBackStrangeAttributes(&attrs);
400 dwarf2reader::DIEHandler *handler
401 = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag, attrs);
402 if (!handler)
403 return NULL;
404 handler->ProcessAttributeString(dwarf2reader::DW_AT_name,
405 dwarf2reader::DW_FORM_strp,
406 name);
407 ProcessStrangeAttributes(handler);
408 if (!handler->EndAttributes()) {
409 handler->Finish();
410 delete handler;
411 return NULL;
412 }
413
414 return handler;
415 }
416
417 DIEHandler *CUFixtureBase::StartSpecifiedDIE(DIEHandler *parent,
418 DwarfTag tag,
419 uint64 specification,
420 const char *name) {
421 dwarf2reader::AttributeList attrs;
422 if (name)
423 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
424 dwarf2reader::DW_FORM_strp));
425 attrs.push_back(make_pair(dwarf2reader::DW_AT_specification,
426 dwarf2reader::DW_FORM_ref4));
427 dwarf2reader::DIEHandler *handler
428 = parent->FindChildHandler(0x8f4c783c0467c989ULL, tag, attrs);
429 if (!handler)
430 return NULL;
431 if (name)
432 handler->ProcessAttributeString(dwarf2reader::DW_AT_name,
433 dwarf2reader::DW_FORM_strp,
434 name);
435 handler->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
436 dwarf2reader::DW_FORM_ref4,
437 specification);
438 if (!handler->EndAttributes()) {
439 handler->Finish();
440 delete handler;
441 return NULL;
442 }
443
444 return handler;
445 }
446
447 void CUFixtureBase::DefineFunction(dwarf2reader::DIEHandler *parent,
448 const string &name, Module::Address address,
449 Module::Address size) {
450 dwarf2reader::AttributeList func_attrs;
451 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
452 dwarf2reader::DW_FORM_strp));
453 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_low_pc,
454 dwarf2reader::DW_FORM_addr));
455 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_high_pc,
456 dwarf2reader::DW_FORM_addr));
457 PushBackStrangeAttributes(&func_attrs);
458 dwarf2reader::DIEHandler *func
459 = parent->FindChildHandler(0xe34797c7e68590a8LL,
460 dwarf2reader::DW_TAG_subprogram,
461 func_attrs);
462 ASSERT_TRUE(func != NULL);
463 func->ProcessAttributeString(dwarf2reader::DW_AT_name,
464 dwarf2reader::DW_FORM_strp,
465 name);
466 func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
467 dwarf2reader::DW_FORM_addr,
468 address);
469 func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
470 dwarf2reader::DW_FORM_addr,
471 address + size);
472 ProcessStrangeAttributes(func);
473 EXPECT_TRUE(func->EndAttributes());
474 func->Finish();
475 delete func;
476 }
477
478 void CUFixtureBase::DeclarationDIE(DIEHandler *parent, uint64 offset,
479 DwarfTag tag,
480 const string &name) {
481 dwarf2reader::AttributeList attrs;
482 if (!name.empty())
483 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
484 dwarf2reader::DW_FORM_strp));
485 attrs.push_back(make_pair(dwarf2reader::DW_AT_declaration,
486 dwarf2reader::DW_FORM_flag));
487 dwarf2reader::DIEHandler *die = parent->FindChildHandler(offset, tag, attrs);
488 ASSERT_TRUE(die != NULL);
489 if (!name.empty())
490 die->ProcessAttributeString(dwarf2reader::DW_AT_name,
491 dwarf2reader::DW_FORM_strp,
492 name);
493 die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_declaration,
494 dwarf2reader::DW_FORM_flag,
495 1);
496 EXPECT_TRUE(die->EndAttributes());
497 die->Finish();
498 delete die;
499 }
500
501 void CUFixtureBase::DefinitionDIE(DIEHandler *parent,
502 DwarfTag tag,
503 uint64 specification,
504 const string &name,
505 Module::Address address,
506 Module::Address size) {
507 dwarf2reader::AttributeList attrs;
508 attrs.push_back(make_pair(dwarf2reader::DW_AT_specification,
509 dwarf2reader::DW_FORM_ref4));
510 if (!name.empty())
511 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
512 dwarf2reader::DW_FORM_strp));
513 if (size) {
514 attrs.push_back(make_pair(dwarf2reader::DW_AT_low_pc,
515 dwarf2reader::DW_FORM_addr));
516 attrs.push_back(make_pair(dwarf2reader::DW_AT_high_pc,
517 dwarf2reader::DW_FORM_addr));
518 }
519 dwarf2reader::DIEHandler *die
520 = parent->FindChildHandler(0x6ccfea031a9e6cc9ULL, tag, attrs);
521 ASSERT_TRUE(die != NULL);
522 die->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
523 dwarf2reader::DW_FORM_ref4,
524 specification);
525 if (!name.empty())
526 die->ProcessAttributeString(dwarf2reader::DW_AT_name,
527 dwarf2reader::DW_FORM_strp,
528 name);
529 if (size) {
530 die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
531 dwarf2reader::DW_FORM_addr,
532 address);
533 die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
534 dwarf2reader::DW_FORM_addr,
535 address + size);
536 }
537 EXPECT_TRUE(die->EndAttributes());
538 die->Finish();
539 delete die;
540 }
541
542 void CUFixtureBase::AbstractInstanceDIE(DIEHandler *parent,
543 uint64 offset,
544 DwarfInline type,
545 uint64 specification,
546 const string &name,
547 DwarfForm form) {
548 dwarf2reader::AttributeList attrs;
549 if (specification != 0ULL)
550 attrs.push_back(make_pair(dwarf2reader::DW_AT_specification,
551 dwarf2reader::DW_FORM_ref4));
552 attrs.push_back(make_pair(dwarf2reader::DW_AT_inline, form));
553 if (!name.empty())
554 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
555 dwarf2reader::DW_FORM_strp));
556 dwarf2reader::DIEHandler *die
557 = parent->FindChildHandler(offset, dwarf2reader::DW_TAG_subprogram, attrs);
558 ASSERT_TRUE(die != NULL);
559 if (specification != 0ULL)
560 die->ProcessAttributeReference(dwarf2reader::DW_AT_specification,
561 dwarf2reader::DW_FORM_ref4,
562 specification);
563 if (form == dwarf2reader::DW_FORM_sdata) {
564 die->ProcessAttributeSigned(dwarf2reader::DW_AT_inline, form, type);
565 } else {
566 die->ProcessAttributeUnsigned(dwarf2reader::DW_AT_inline, form, type);
567 }
568 if (!name.empty())
569 die->ProcessAttributeString(dwarf2reader::DW_AT_name,
570 dwarf2reader::DW_FORM_strp,
571 name);
572
573 EXPECT_TRUE(die->EndAttributes());
574 die->Finish();
575 delete die;
576 }
577
578 void CUFixtureBase::DefineInlineInstanceDIE(DIEHandler *parent,
579 const string &name,
580 uint64 origin,
581 Module::Address address,
582 Module::Address size) {
583 dwarf2reader::AttributeList func_attrs;
584 if (!name.empty())
585 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
586 dwarf2reader::DW_FORM_strp));
587 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_low_pc,
588 dwarf2reader::DW_FORM_addr));
589 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_high_pc,
590 dwarf2reader::DW_FORM_addr));
591 func_attrs.push_back(make_pair(dwarf2reader::DW_AT_abstract_origin,
592 dwarf2reader::DW_FORM_ref4));
593 PushBackStrangeAttributes(&func_attrs);
594 dwarf2reader::DIEHandler *func
595 = parent->FindChildHandler(0x11c70f94c6e87ccdLL,
596 dwarf2reader::DW_TAG_subprogram,
597 func_attrs);
598 ASSERT_TRUE(func != NULL);
599 if (!name.empty()) {
600 func->ProcessAttributeString(dwarf2reader::DW_AT_name,
601 dwarf2reader::DW_FORM_strp,
602 name);
603 }
604 func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_low_pc,
605 dwarf2reader::DW_FORM_addr,
606 address);
607 func->ProcessAttributeUnsigned(dwarf2reader::DW_AT_high_pc,
608 dwarf2reader::DW_FORM_addr,
609 address + size);
610 func->ProcessAttributeReference(dwarf2reader::DW_AT_abstract_origin,
611 dwarf2reader::DW_FORM_ref4,
612 origin);
613 ProcessStrangeAttributes(func);
614 EXPECT_TRUE(func->EndAttributes());
615 func->Finish();
616 delete func;
617 }
618
619 void CUFixtureBase::FillFunctions() {
620 if (functions_filled_)
621 return;
622 module_.GetFunctions(&functions_, functions_.end());
623 sort(functions_.begin(), functions_.end(),
624 Module::Function::CompareByAddress);
625 functions_filled_ = true;
626 }
627
628 void CUFixtureBase::TestFunctionCount(size_t expected) {
629 FillFunctions();
630 ASSERT_EQ(expected, functions_.size());
631 }
632
633 void CUFixtureBase::TestFunction(int i, const string &name,
634 Module::Address address,
635 Module::Address size) {
636 FillFunctions();
637 ASSERT_LT((size_t) i, functions_.size());
638
639 Module::Function *function = functions_[i];
640 EXPECT_EQ(name, function->name);
641 EXPECT_EQ(address, function->address);
642 EXPECT_EQ(size, function->size);
643 EXPECT_EQ(0U, function->parameter_size);
644 }
645
646 void CUFixtureBase::TestLineCount(int i, size_t expected) {
647 FillFunctions();
648 ASSERT_LT((size_t) i, functions_.size());
649
650 ASSERT_EQ(expected, functions_[i]->lines.size());
651 }
652
653 void CUFixtureBase::TestLine(int i, int j,
654 Module::Address address, Module::Address size,
655 const string &filename, int number) {
656 FillFunctions();
657 ASSERT_LT((size_t) i, functions_.size());
658 ASSERT_LT((size_t) j, functions_[i]->lines.size());
659
660 Module::Line *line = &functions_[i]->lines[j];
661 EXPECT_EQ(address, line->address);
662 EXPECT_EQ(size, line->size);
663 EXPECT_EQ(filename, line->file->name.c_str());
664 EXPECT_EQ(number, line->number);
665 }
666
667 // Include caller locations for our test subroutines.
668 #define TRACE(call) do { SCOPED_TRACE("called from here"); call; } while (0)
669 #define PushLine(a,b,c,d) TRACE(PushLine((a),(b),(c),(d)))
670 #define SetLanguage(a) TRACE(SetLanguage(a))
671 #define StartCU() TRACE(StartCU())
672 #define DefineFunction(a,b,c,d) TRACE(DefineFunction((a),(b),(c),(d)))
673 #define DeclarationDIE(a,b,c,d) TRACE(DeclarationDIE((a),(b),(c),(d)))
674 #define DefinitionDIE(a,b,c,d,e,f) TRACE(DefinitionDIE((a),(b),(c),(d),(e),(f)))
675 #define TestFunctionCount(a) TRACE(TestFunctionCount(a))
676 #define TestFunction(a,b,c,d) TRACE(TestFunction((a),(b),(c),(d)))
677 #define TestLineCount(a,b) TRACE(TestLineCount((a),(b)))
678 #define TestLine(a,b,c,d,e,f) TRACE(TestLine((a),(b),(c),(d),(e),(f)))
679
680 class Simple: public CUFixtureBase, public Test {
681 };
682
683 TEST_F(Simple, OneFunc) {
684 PushLine(0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file", 246571772);
685
686 StartCU();
687 DefineFunction(&root_handler_, "function1",
688 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
689 root_handler_.Finish();
690
691 TestFunctionCount(1);
692 TestFunction(0, "function1", 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL);
693 TestLineCount(0, 1);
694 TestLine(0, 0, 0x938cf8c07def4d34ULL, 0x55592d727f6cd01fLL, "line-file",
695 246571772);
696 }
697
698 TEST_F(Simple, IrrelevantRootChildren) {
699 StartCU();
700 dwarf2reader::AttributeList no_attrs;
701 EXPECT_FALSE(root_handler_
702 .FindChildHandler(0x7db32bff4e2dcfb1ULL,
703 dwarf2reader::DW_TAG_lexical_block, no_attrs));
704 }
705
706 TEST_F(Simple, IrrelevantNamedScopeChildren) {
707 StartCU();
708 dwarf2reader::AttributeList no_attrs;
709 DIEHandler *class_A_handler
710 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A");
711 EXPECT_TRUE(class_A_handler != NULL);
712 EXPECT_FALSE(class_A_handler
713 ->FindChildHandler(0x02e55999b865e4e9ULL,
714 dwarf2reader::DW_TAG_lexical_block,
715 no_attrs));
716 delete class_A_handler;
717 }
718
719 // Verify that FileContexts can safely be deleted unused.
720 TEST_F(Simple, UnusedFileContext) {
721 Module m("module-name", "module-os", "module-arch", "module-id");
722 DwarfCUToModule::FileContext fc("dwarf-filename", &m);
723
724 // Kludge: satisfy reporter_'s expectation.
725 reporter_.SetCUName("compilation-unit-name");
726 }
727
728 TEST_F(Simple, InlineFunction) {
729 PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);
730
731 StartCU();
732 AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
733 dwarf2reader::DW_INL_inlined, 0, "inline-name");
734 DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL,
735 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
736 root_handler_.Finish();
737
738 TestFunctionCount(1);
739 TestFunction(0, "inline-name",
740 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
741 }
742
743 TEST_F(Simple, InlineFunctionSignedAttribute) {
744 PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);
745
746 StartCU();
747 AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
748 dwarf2reader::DW_INL_inlined, 0, "inline-name",
749 dwarf2reader::DW_FORM_sdata);
750 DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL,
751 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
752 root_handler_.Finish();
753
754 TestFunctionCount(1);
755 TestFunction(0, "inline-name",
756 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
757 }
758
759 // Any DIE with an DW_AT_inline attribute can be cited by
760 // DW_AT_abstract_origin attributes --- even if the value of the
761 // DW_AT_inline attribute is DW_INL_not_inlined.
762 TEST_F(Simple, AbstractOriginNotInlined) {
763 PushLine(0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL, "line-file", 6111581);
764
765 StartCU();
766 AbstractInstanceDIE(&root_handler_, 0x93e9cdad52826b39ULL,
767 dwarf2reader::DW_INL_not_inlined, 0, "abstract-instance");
768 DefineInlineInstanceDIE(&root_handler_, "", 0x93e9cdad52826b39ULL,
769 0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL);
770 root_handler_.Finish();
771
772 TestFunctionCount(1);
773 TestFunction(0, "abstract-instance",
774 0x2805c4531be6ca0eULL, 0x686b52155a8d4d2cULL);
775 }
776
777 TEST_F(Simple, UnknownAbstractOrigin) {
778 EXPECT_CALL(reporter_, UnknownAbstractOrigin(_, 1ULL)).WillOnce(Return());
779 PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);
780
781 StartCU();
782 AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
783 dwarf2reader::DW_INL_inlined, 0, "inline-name");
784 DefineInlineInstanceDIE(&root_handler_, "", 1ULL,
785 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
786 root_handler_.Finish();
787
788 TestFunctionCount(1);
789 TestFunction(0, "",
790 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
791 }
792
793 // An address range.
794 struct Range {
795 Module::Address start, end;
796 };
797
798 // Test data for pairing functions and lines.
799 struct Situation {
800 // Two function intervals, and two line intervals.
801 Range functions[2], lines[2];
802
803 // The number of lines we expect to be assigned to each of the
804 // functions, and the address ranges.
805 int paired_count[2];
806 Range paired[2][2];
807
808 // The number of functions that are not entirely covered by lines,
809 // and vice versa.
810 int uncovered_functions, uncovered_lines;
811 };
812
813 #define PAIRING(func1_start, func1_end, func2_start, func2_end, \
814 line1_start, line1_end, line2_start, line2_end, \
815 func1_num_lines, func2_num_lines, \
816 func1_line1_start, func1_line1_end, \
817 func1_line2_start, func1_line2_end, \
818 func2_line1_start, func2_line1_end, \
819 func2_line2_start, func2_line2_end, \
820 uncovered_functions, uncovered_lines) \
821 { { { func1_start, func1_end }, { func2_start, func2_end } }, \
822 { { line1_start, line1_end }, { line2_start, line2_end } }, \
823 { func1_num_lines, func2_num_lines }, \
824 { { { func1_line1_start, func1_line1_end }, \
825 { func1_line2_start, func1_line2_end } }, \
826 { { func2_line1_start, func2_line1_end }, \
827 { func2_line2_start, func2_line2_end } } }, \
828 uncovered_functions, uncovered_lines },
829
830 Situation situations[] = {
831 #include "common/testdata/func-line-pairing.h"
832 };
833
834 #undef PAIRING
835
836 class FuncLinePairing: public CUFixtureBase,
837 public TestWithParam<Situation> { };
838
839 INSTANTIATE_TEST_CASE_P(AllSituations, FuncLinePairing,
840 ValuesIn(situations));
841
842 TEST_P(FuncLinePairing, Pairing) {
843 const Situation &s = GetParam();
844 PushLine(s.lines[0].start,
845 s.lines[0].end - s.lines[0].start,
846 "line-file", 67636963);
847 PushLine(s.lines[1].start,
848 s.lines[1].end - s.lines[1].start,
849 "line-file", 67636963);
850 if (s.uncovered_functions)
851 EXPECT_CALL(reporter_, UncoveredFunction(_))
852 .Times(s.uncovered_functions)
853 .WillRepeatedly(Return());
854 if (s.uncovered_lines)
855 EXPECT_CALL(reporter_, UncoveredLine(_))
856 .Times(s.uncovered_lines)
857 .WillRepeatedly(Return());
858
859 StartCU();
860 DefineFunction(&root_handler_, "function1",
861 s.functions[0].start,
862 s.functions[0].end - s.functions[0].start);
863 DefineFunction(&root_handler_, "function2",
864 s.functions[1].start,
865 s.functions[1].end - s.functions[1].start);
866 root_handler_.Finish();
867
868 TestFunctionCount(2);
869 TestFunction(0, "function1",
870 s.functions[0].start,
871 s.functions[0].end - s.functions[0].start);
872 TestLineCount(0, s.paired_count[0]);
873 for (int i = 0; i < s.paired_count[0]; i++)
874 TestLine(0, i, s.paired[0][i].start,
875 s.paired[0][i].end - s.paired[0][i].start,
876 "line-file", 67636963);
877 TestFunction(1, "function2",
878 s.functions[1].start,
879 s.functions[1].end - s.functions[1].start);
880 TestLineCount(1, s.paired_count[1]);
881 for (int i = 0; i < s.paired_count[1]; i++)
882 TestLine(1, i, s.paired[1][i].start,
883 s.paired[1][i].end - s.paired[1][i].start,
884 "line-file", 67636963);
885 }
886
887 TEST_F(FuncLinePairing, EmptyCU) {
888
889 StartCU();
890 root_handler_.Finish();
891
892 TestFunctionCount(0);
893 }
894
895 TEST_F(FuncLinePairing, LinesNoFuncs) {
896 PushLine(40, 2, "line-file", 82485646);
897 EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return());
898
899 StartCU();
900 root_handler_.Finish();
901
902 TestFunctionCount(0);
903 }
904
905 TEST_F(FuncLinePairing, FuncsNoLines) {
906 EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
907
908 StartCU();
909 DefineFunction(&root_handler_, "function1", 0x127da12ffcf5c51fULL, 0x1000U);
910 root_handler_.Finish();
911
912 TestFunctionCount(1);
913 TestFunction(0, "function1", 0x127da12ffcf5c51fULL, 0x1000U);
914 }
915
916 TEST_F(FuncLinePairing, GapThenFunction) {
917 PushLine(20, 2, "line-file-2", 174314698);
918 PushLine(10, 2, "line-file-1", 263008005);
919
920 StartCU();
921 DefineFunction(&root_handler_, "function1", 10, 2);
922 DefineFunction(&root_handler_, "function2", 20, 2);
923 root_handler_.Finish();
924
925 TestFunctionCount(2);
926 TestFunction(0, "function1", 10, 2);
927 TestLineCount(0, 1);
928 TestLine(0, 0, 10, 2, "line-file-1", 263008005);
929 TestFunction(1, "function2", 20, 2);
930 TestLineCount(1, 1);
931 TestLine(1, 0, 20, 2, "line-file-2", 174314698);
932 }
933
934 // If GCC emits padding after one function to align the start of
935 // the next, then it will attribute the padding instructions to
936 // the last source line of function (to reduce the size of the
937 // line number info), but omit it from the DW_AT_{low,high}_pc
938 // range given in .debug_info (since it costs nothing to be
939 // precise there). If we did use at least some of the line
940 // we're about to skip, then assume this is what happened, and
941 // don't warn.
942 TEST_F(FuncLinePairing, GCCAlignmentStretch) {
943 PushLine(10, 10, "line-file", 63351048);
944 PushLine(20, 10, "line-file", 61661044);
945
946 StartCU();
947 DefineFunction(&root_handler_, "function1", 10, 5);
948 // five-byte gap between functions, covered by line 63351048.
949 // This should not elicit a warning.
950 DefineFunction(&root_handler_, "function2", 20, 10);
951 root_handler_.Finish();
952
953 TestFunctionCount(2);
954 TestFunction(0, "function1", 10, 5);
955 TestLineCount(0, 1);
956 TestLine(0, 0, 10, 5, "line-file", 63351048);
957 TestFunction(1, "function2", 20, 10);
958 TestLineCount(1, 1);
959 TestLine(1, 0, 20, 10, "line-file", 61661044);
960 }
961
962 // Unfortunately, neither the DWARF parser's handler interface nor the
963 // DIEHandler interface is capable of expressing a function that abuts
964 // the end of the address space: the high_pc value looks like zero.
965
966 TEST_F(FuncLinePairing, LineAtEndOfAddressSpace) {
967 PushLine(0xfffffffffffffff0ULL, 16, "line-file", 63351048);
968 EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return());
969
970 StartCU();
971 DefineFunction(&root_handler_, "function1", 0xfffffffffffffff0ULL, 6);
972 DefineFunction(&root_handler_, "function2", 0xfffffffffffffffaULL, 5);
973 root_handler_.Finish();
974
975 TestFunctionCount(2);
976 TestFunction(0, "function1", 0xfffffffffffffff0ULL, 6);
977 TestLineCount(0, 1);
978 TestLine(0, 0, 0xfffffffffffffff0ULL, 6, "line-file", 63351048);
979 TestFunction(1, "function2", 0xfffffffffffffffaULL, 5);
980 TestLineCount(1, 1);
981 TestLine(1, 0, 0xfffffffffffffffaULL, 5, "line-file", 63351048);
982 }
983
984 // A function with more than one uncovered area should only be warned
985 // about once.
986 TEST_F(FuncLinePairing, WarnOnceFunc) {
987 PushLine(20, 1, "line-file-2", 262951329);
988 PushLine(11, 1, "line-file-1", 219964021);
989 EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
990
991 StartCU();
992 DefineFunction(&root_handler_, "function", 10, 11);
993 root_handler_.Finish();
994
995 TestFunctionCount(1);
996 TestFunction(0, "function", 10, 11);
997 TestLineCount(0, 2);
998 TestLine(0, 0, 11, 1, "line-file-1", 219964021);
999 TestLine(0, 1, 20, 1, "line-file-2", 262951329);
1000 }
1001
1002 // A line with more than one uncovered area should only be warned
1003 // about once.
1004 TEST_F(FuncLinePairing, WarnOnceLine) {
1005 PushLine(10, 20, "filename1", 118581871);
1006 EXPECT_CALL(reporter_, UncoveredLine(_)).WillOnce(Return());
1007
1008 StartCU();
1009 DefineFunction(&root_handler_, "function1", 11, 1);
1010 DefineFunction(&root_handler_, "function2", 13, 1);
1011 root_handler_.Finish();
1012
1013 TestFunctionCount(2);
1014 TestFunction(0, "function1", 11, 1);
1015 TestLineCount(0, 1);
1016 TestLine(0, 0, 11, 1, "filename1", 118581871);
1017 TestFunction(1, "function2", 13, 1);
1018 TestLineCount(1, 1);
1019 TestLine(1, 0, 13, 1, "filename1", 118581871);
1020 }
1021
1022 class CXXQualifiedNames: public CUFixtureBase,
1023 public TestWithParam<DwarfTag> { };
1024
1025 INSTANTIATE_TEST_CASE_P(VersusEnclosures, CXXQualifiedNames,
1026 Values(dwarf2reader::DW_TAG_class_type,
1027 dwarf2reader::DW_TAG_structure_type,
1028 dwarf2reader::DW_TAG_union_type,
1029 dwarf2reader::DW_TAG_namespace));
1030
1031 TEST_P(CXXQualifiedNames, TwoFunctions) {
1032 DwarfTag tag = GetParam();
1033
1034 SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
1035 PushLine(10, 1, "filename1", 69819327);
1036 PushLine(20, 1, "filename2", 95115701);
1037
1038 StartCU();
1039 DIEHandler *enclosure_handler = StartNamedDIE(&root_handler_, tag,
1040 "Enclosure");
1041 EXPECT_TRUE(enclosure_handler != NULL);
1042 DefineFunction(enclosure_handler, "func_B", 10, 1);
1043 DefineFunction(enclosure_handler, "func_C", 20, 1);
1044 enclosure_handler->Finish();
1045 delete enclosure_handler;
1046 root_handler_.Finish();
1047
1048 TestFunctionCount(2);
1049 TestFunction(0, "Enclosure::func_B", 10, 1);
1050 TestFunction(1, "Enclosure::func_C", 20, 1);
1051 }
1052
1053 TEST_P(CXXQualifiedNames, FuncInEnclosureInNamespace) {
1054 DwarfTag tag = GetParam();
1055
1056 SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
1057 PushLine(10, 1, "line-file", 69819327);
1058
1059 StartCU();
1060 DIEHandler *namespace_handler
1061 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
1062 "Namespace");
1063 EXPECT_TRUE(namespace_handler != NULL);
1064 DIEHandler *enclosure_handler = StartNamedDIE(namespace_handler, tag,
1065 "Enclosure");
1066 EXPECT_TRUE(enclosure_handler != NULL);
1067 DefineFunction(enclosure_handler, "function", 10, 1);
1068 enclosure_handler->Finish();
1069 delete enclosure_handler;
1070 namespace_handler->Finish();
1071 delete namespace_handler;
1072 root_handler_.Finish();
1073
1074 TestFunctionCount(1);
1075 TestFunction(0, "Namespace::Enclosure::function", 10, 1);
1076 }
1077
1078 TEST_F(CXXQualifiedNames, FunctionInClassInStructInNamespace) {
1079 SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
1080 PushLine(10, 1, "filename1", 69819327);
1081
1082 StartCU();
1083 DIEHandler *namespace_handler
1084 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
1085 "namespace_A");
1086 EXPECT_TRUE(namespace_handler != NULL);
1087 DIEHandler *struct_handler
1088 = StartNamedDIE(namespace_handler, dwarf2reader::DW_TAG_structure_type,
1089 "struct_B");
1090 EXPECT_TRUE(struct_handler != NULL);
1091 DIEHandler *class_handler
1092 = StartNamedDIE(struct_handler, dwarf2reader::DW_TAG_class_type,
1093 "class_C");
1094 DefineFunction(class_handler, "function_D", 10, 1);
1095 class_handler->Finish();
1096 delete class_handler;
1097 struct_handler->Finish();
1098 delete struct_handler;
1099 namespace_handler->Finish();
1100 delete namespace_handler;
1101 root_handler_.Finish();
1102
1103 TestFunctionCount(1);
1104 TestFunction(0, "namespace_A::struct_B::class_C::function_D", 10, 1);
1105 }
1106
1107 struct LanguageAndQualifiedName {
1108 dwarf2reader::DwarfLanguage language;
1109 const char *name;
1110 };
1111
1112 const LanguageAndQualifiedName LanguageAndQualifiedNameCases[] = {
1113 { dwarf2reader::DW_LANG_none, "class_A::function_B" },
1114 { dwarf2reader::DW_LANG_C, "class_A::function_B" },
1115 { dwarf2reader::DW_LANG_C89, "class_A::function_B" },
1116 { dwarf2reader::DW_LANG_C99, "class_A::function_B" },
1117 { dwarf2reader::DW_LANG_C_plus_plus, "class_A::function_B" },
1118 { dwarf2reader::DW_LANG_Java, "class_A.function_B" },
1119 { dwarf2reader::DW_LANG_Cobol74, "class_A::function_B" },
1120 { dwarf2reader::DW_LANG_Mips_Assembler, NULL }
1121 };
1122
1123 class QualifiedForLanguage:
1124 public CUFixtureBase,
1125 public TestWithParam<LanguageAndQualifiedName> { };
1126
1127 INSTANTIATE_TEST_CASE_P(LanguageAndQualifiedName, QualifiedForLanguage,
1128 ValuesIn(LanguageAndQualifiedNameCases));
1129
1130 TEST_P(QualifiedForLanguage, MemberFunction) {
1131 const LanguageAndQualifiedName &param = GetParam();
1132
1133 PushLine(10, 1, "line-file", 212966758);
1134 SetLanguage(param.language);
1135
1136 StartCU();
1137 DIEHandler *class_handler
1138 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1139 "class_A");
1140 DefineFunction(class_handler, "function_B", 10, 1);
1141 class_handler->Finish();
1142 delete class_handler;
1143 root_handler_.Finish();
1144
1145 if (param.name) {
1146 TestFunctionCount(1);
1147 TestFunction(0, param.name, 10, 1);
1148 } else {
1149 TestFunctionCount(0);
1150 }
1151 }
1152
1153 TEST_P(QualifiedForLanguage, MemberFunctionSignedLanguage) {
1154 const LanguageAndQualifiedName &param = GetParam();
1155
1156 PushLine(10, 1, "line-file", 212966758);
1157 SetLanguage(param.language);
1158 SetLanguageSigned(true);
1159
1160 StartCU();
1161 DIEHandler *class_handler
1162 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1163 "class_A");
1164 DefineFunction(class_handler, "function_B", 10, 1);
1165 class_handler->Finish();
1166 delete class_handler;
1167 root_handler_.Finish();
1168
1169 if (param.name) {
1170 TestFunctionCount(1);
1171 TestFunction(0, param.name, 10, 1);
1172 } else {
1173 TestFunctionCount(0);
1174 }
1175 }
1176
1177 class Specifications: public CUFixtureBase, public Test { };
1178
1179 TEST_F(Specifications, Function) {
1180 PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);
1181
1182 StartCU();
1183 DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
1184 dwarf2reader::DW_TAG_subprogram, "declaration-name");
1185 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1186 0xcd3c51b946fb1eeeLL, "",
1187 0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
1188 root_handler_.Finish();
1189
1190 TestFunctionCount(1);
1191 TestFunction(0, "declaration-name",
1192 0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
1193 }
1194
1195 TEST_F(Specifications, MemberFunction) {
1196 PushLine(0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL, "line-file", 18116691);
1197
1198 StartCU();
1199 DIEHandler *class_handler
1200 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "class_A");
1201 DeclarationDIE(class_handler, 0x7d83028c431406e8ULL,
1202 dwarf2reader::DW_TAG_subprogram, "declaration-name");
1203 class_handler->Finish();
1204 delete class_handler;
1205 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1206 0x7d83028c431406e8ULL, "",
1207 0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL);
1208 root_handler_.Finish();
1209
1210 TestFunctionCount(1);
1211 TestFunction(0, "class_A::declaration-name",
1212 0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL);
1213 }
1214
1215 // This case should gather the name from both the definition and the
1216 // declaration's parent.
1217 TEST_F(Specifications, FunctionDeclarationParent) {
1218 PushLine(0x463c9ddf405be227ULL, 0x6a47774af5049680ULL, "line-file", 70254922);
1219
1220 StartCU();
1221 {
1222 DIEHandler *class_handler
1223 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1224 "class_A");
1225 ASSERT_TRUE(class_handler != NULL);
1226 DeclarationDIE(class_handler, 0x0e0e877c8404544aULL,
1227 dwarf2reader::DW_TAG_subprogram, "declaration-name");
1228 class_handler->Finish();
1229 delete class_handler;
1230 }
1231
1232 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1233 0x0e0e877c8404544aULL, "definition-name",
1234 0x463c9ddf405be227ULL, 0x6a47774af5049680ULL);
1235
1236 root_handler_.Finish();
1237
1238 TestFunctionCount(1);
1239 TestFunction(0, "class_A::definition-name",
1240 0x463c9ddf405be227ULL, 0x6a47774af5049680ULL);
1241 }
1242
1243 // Named scopes should also gather enclosing name components from
1244 // their declarations.
1245 TEST_F(Specifications, NamedScopeDeclarationParent) {
1246 PushLine(0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL, "line-file", 77392604);
1247
1248 StartCU();
1249 {
1250 DIEHandler *space_handler
1251 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
1252 "space_A");
1253 ASSERT_TRUE(space_handler != NULL);
1254 DeclarationDIE(space_handler, 0x419bb1d12f9a73a2ULL,
1255 dwarf2reader::DW_TAG_class_type, "class-declaration-name");
1256 space_handler->Finish();
1257 delete space_handler;
1258 }
1259
1260 {
1261 DIEHandler *class_handler
1262 = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1263 0x419bb1d12f9a73a2ULL, "class-definition-name");
1264 ASSERT_TRUE(class_handler != NULL);
1265 DefineFunction(class_handler, "function",
1266 0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL);
1267 class_handler->Finish();
1268 delete class_handler;
1269 }
1270
1271 root_handler_.Finish();
1272
1273 TestFunctionCount(1);
1274 TestFunction(0, "space_A::class-definition-name::function",
1275 0x5d13433d0df13d00ULL, 0x48ebebe5ade2cab4ULL);
1276 }
1277
1278 // This test recreates bug 364.
1279 TEST_F(Specifications, InlineFunction) {
1280 PushLine(0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL, "line-file", 75173118);
1281
1282 StartCU();
1283 DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
1284 dwarf2reader::DW_TAG_subprogram, "inline-name");
1285 AbstractInstanceDIE(&root_handler_, 0x1e8dac5d507ed7abULL,
1286 dwarf2reader::DW_INL_inlined, 0xcd3c51b946fb1eeeLL, "");
1287 DefineInlineInstanceDIE(&root_handler_, "", 0x1e8dac5d507ed7abULL,
1288 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
1289 root_handler_.Finish();
1290
1291 TestFunctionCount(1);
1292 TestFunction(0, "inline-name",
1293 0x1758a0f941b71efbULL, 0x1cf154f1f545e146ULL);
1294 }
1295
1296 // Check name construction for a long chain containing each combination of:
1297 // - struct, union, class, namespace
1298 // - direct and definition
1299 TEST_F(Specifications, LongChain) {
1300 PushLine(0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL, "line-file", 21192926);
1301 SetLanguage(dwarf2reader::DW_LANG_C_plus_plus);
1302
1303 StartCU();
1304 // The structure we're building here is:
1305 // space_A full definition
1306 // space_B declaration
1307 // space_B definition
1308 // struct_C full definition
1309 // struct_D declaration
1310 // struct_D definition
1311 // union_E full definition
1312 // union_F declaration
1313 // union_F definition
1314 // class_G full definition
1315 // class_H declaration
1316 // class_H definition
1317 // func_I declaration
1318 // func_I definition
1319 //
1320 // So:
1321 // - space_A, struct_C, union_E, and class_G don't use specifications;
1322 // - space_B, struct_D, union_F, and class_H do.
1323 // - func_I uses a specification.
1324 //
1325 // The full name for func_I is thus:
1326 //
1327 // space_A::space_B::struct_C::struct_D::union_E::union_F::
1328 // class_G::class_H::func_I
1329 {
1330 DIEHandler *space_A_handler
1331 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
1332 "space_A");
1333 DeclarationDIE(space_A_handler, 0x2e111126496596e2ULL,
1334 dwarf2reader::DW_TAG_namespace, "space_B");
1335 space_A_handler->Finish();
1336 delete space_A_handler;
1337 }
1338
1339 {
1340 DIEHandler *space_B_handler
1341 = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_namespace,
1342 0x2e111126496596e2ULL);
1343 DIEHandler *struct_C_handler
1344 = StartNamedDIE(space_B_handler, dwarf2reader::DW_TAG_structure_type,
1345 "struct_C");
1346 DeclarationDIE(struct_C_handler, 0x20cd423bf2a25a4cULL,
1347 dwarf2reader::DW_TAG_structure_type, "struct_D");
1348 struct_C_handler->Finish();
1349 delete struct_C_handler;
1350 space_B_handler->Finish();
1351 delete space_B_handler;
1352 }
1353
1354 {
1355 DIEHandler *struct_D_handler
1356 = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_structure_type,
1357 0x20cd423bf2a25a4cULL);
1358 DIEHandler *union_E_handler
1359 = StartNamedDIE(struct_D_handler, dwarf2reader::DW_TAG_union_type,
1360 "union_E");
1361 DeclarationDIE(union_E_handler, 0xe25c84805aa58c32ULL,
1362 dwarf2reader::DW_TAG_union_type, "union_F");
1363 union_E_handler->Finish();
1364 delete union_E_handler;
1365 struct_D_handler->Finish();
1366 delete struct_D_handler;
1367 }
1368
1369 {
1370 DIEHandler *union_F_handler
1371 = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_union_type,
1372 0xe25c84805aa58c32ULL);
1373 DIEHandler *class_G_handler
1374 = StartNamedDIE(union_F_handler, dwarf2reader::DW_TAG_class_type,
1375 "class_G");
1376 DeclarationDIE(class_G_handler, 0xb70d960dcc173b6eULL,
1377 dwarf2reader::DW_TAG_class_type, "class_H");
1378 class_G_handler->Finish();
1379 delete class_G_handler;
1380 union_F_handler->Finish();
1381 delete union_F_handler;
1382 }
1383
1384 {
1385 DIEHandler *class_H_handler
1386 = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1387 0xb70d960dcc173b6eULL);
1388 DeclarationDIE(class_H_handler, 0x27ff829e3bf69f37ULL,
1389 dwarf2reader::DW_TAG_subprogram, "func_I");
1390 class_H_handler->Finish();
1391 delete class_H_handler;
1392 }
1393
1394 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1395 0x27ff829e3bf69f37ULL, "",
1396 0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL);
1397 root_handler_.Finish();
1398
1399 TestFunctionCount(1);
1400 TestFunction(0, "space_A::space_B::struct_C::struct_D::union_E::union_F"
1401 "::class_G::class_H::func_I",
1402 0x5a0dd6bb85db754cULL, 0x3bccb213d08c7fd3ULL);
1403 }
1404
1405 TEST_F(Specifications, InterCU) {
1406 Module m("module-name", "module-os", "module-arch", "module-id");
1407 DwarfCUToModule::FileContext fc("dwarf-filename", &m);
1408 EXPECT_CALL(reporter_, UncoveredFunction(_)).WillOnce(Return());
1409 MockLineToModuleFunctor lr;
1410 EXPECT_CALL(lr, mock_apply(_,_,_,_)).Times(0);
1411 dwarf2reader::AttributeList no_attrs;
1412
1413 // Kludge: satisfy reporter_'s expectation.
1414 reporter_.SetCUName("compilation-unit-name");
1415
1416 // First CU. Declares class_A.
1417 {
1418 DwarfCUToModule root1_handler(&fc, &lr, &reporter_);
1419 ASSERT_TRUE(root1_handler.StartCompilationUnit(0, 1, 2, 3, 3));
1420 dwarf2reader::AttributeList attrs;
1421 PushBackStrangeAttributes(&attrs);
1422 ASSERT_TRUE(root1_handler.StartRootDIE(1, dwarf2reader::DW_TAG_compile_unit,
1423 attrs));
1424 ProcessStrangeAttributes(&root1_handler);
1425 ASSERT_TRUE(root1_handler.EndAttributes());
1426 DeclarationDIE(&root1_handler, 0xb8fbfdd5f0b26fceULL,
1427 dwarf2reader::DW_TAG_class_type, "class_A");
1428 root1_handler.Finish();
1429 }
1430
1431 // Second CU. Defines class_A, declares member_func_B.
1432 {
1433 DwarfCUToModule root2_handler(&fc, &lr, &reporter_);
1434 ASSERT_TRUE(root2_handler.StartCompilationUnit(0, 1, 2, 3, 3));
1435 ASSERT_TRUE(root2_handler.StartRootDIE(1, dwarf2reader::DW_TAG_compile_unit,
1436 no_attrs));
1437 ASSERT_TRUE(root2_handler.EndAttributes());
1438 DIEHandler *class_A_handler
1439 = StartSpecifiedDIE(&root2_handler, dwarf2reader::DW_TAG_class_type,
1440 0xb8fbfdd5f0b26fceULL);
1441 DeclarationDIE(class_A_handler, 0xb01fef8b380bd1a2ULL,
1442 dwarf2reader::DW_TAG_subprogram, "member_func_B");
1443 class_A_handler->Finish();
1444 delete class_A_handler;
1445 root2_handler.Finish();
1446 }
1447
1448 // Third CU. Defines member_func_B.
1449 {
1450 DwarfCUToModule root3_handler(&fc, &lr, &reporter_);
1451 ASSERT_TRUE(root3_handler.StartCompilationUnit(0, 1, 2, 3, 3));
1452 ASSERT_TRUE(root3_handler.StartRootDIE(1, dwarf2reader::DW_TAG_compile_unit,
1453 no_attrs));
1454 ASSERT_TRUE(root3_handler.EndAttributes());
1455 DefinitionDIE(&root3_handler, dwarf2reader::DW_TAG_subprogram,
1456 0xb01fef8b380bd1a2ULL, "",
1457 0x2618f00a1a711e53ULL, 0x4fd94b76d7c2caf5ULL);
1458 root3_handler.Finish();
1459 }
1460
1461 vector<Module::Function *> functions;
1462 m.GetFunctions(&functions, functions.end());
1463 EXPECT_EQ(1U, functions.size());
1464 EXPECT_STREQ("class_A::member_func_B", functions[0]->name.c_str());
1465 }
1466
1467 TEST_F(Specifications, BadOffset) {
1468 PushLine(0xa0277efd7ce83771ULL, 0x149554a184c730c1ULL, "line-file", 56636272);
1469 EXPECT_CALL(reporter_, UnknownSpecification(_, 0x2be953efa6f9a996ULL))
1470 .WillOnce(Return());
1471
1472 StartCU();
1473 DeclarationDIE(&root_handler_, 0xefd7f7752c27b7e4ULL,
1474 dwarf2reader::DW_TAG_subprogram, "function");
1475 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1476 0x2be953efa6f9a996ULL, "",
1477 0xa0277efd7ce83771ULL, 0x149554a184c730c1ULL);
1478 root_handler_.Finish();
1479 }
1480
1481 TEST_F(Specifications, FunctionDefinitionHasOwnName) {
1482 PushLine(0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL, "line-file", 56792403);
1483
1484 StartCU();
1485 DeclarationDIE(&root_handler_, 0xc34ff4786cae78bdULL,
1486 dwarf2reader::DW_TAG_subprogram, "declaration-name");
1487 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1488 0xc34ff4786cae78bdULL, "definition-name",
1489 0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL);
1490 root_handler_.Finish();
1491
1492 TestFunctionCount(1);
1493 TestFunction(0, "definition-name",
1494 0xced50b3eea81022cULL, 0x08dd4d301cc7a7d2ULL);
1495 }
1496
1497 TEST_F(Specifications, ClassDefinitionHasOwnName) {
1498 PushLine(0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL, "line-file", 57119241);
1499
1500 StartCU();
1501 DeclarationDIE(&root_handler_, 0xd0fe467ec2f1a58cULL,
1502 dwarf2reader::DW_TAG_class_type, "class-declaration-name");
1503
1504 dwarf2reader::DIEHandler *class_definition
1505 = StartSpecifiedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1506 0xd0fe467ec2f1a58cULL, "class-definition-name");
1507 ASSERT_TRUE(class_definition);
1508 DeclarationDIE(class_definition, 0x6d028229c15623dbULL,
1509 dwarf2reader::DW_TAG_subprogram,
1510 "function-declaration-name");
1511 class_definition->Finish();
1512 delete class_definition;
1513
1514 DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
1515 0x6d028229c15623dbULL, "function-definition-name",
1516 0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL);
1517
1518 root_handler_.Finish();
1519
1520 TestFunctionCount(1);
1521 TestFunction(0, "class-definition-name::function-definition-name",
1522 0x1d0f5e0f6ce309bdULL, 0x654e1852ec3599e7ULL);
1523 }
1524
1525 // DIEs that cite a specification should prefer the specification's
1526 // parents over their own when choosing qualified names. In this test,
1527 // we take the name from our definition but the enclosing scope name
1528 // from our declaration. I don't see why they'd ever be different, but
1529 // we want to verify what DwarfCUToModule is looking at.
1530 TEST_F(Specifications, PreferSpecificationParents) {
1531 PushLine(0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL, "line-file", 79488694);
1532
1533 StartCU();
1534 {
1535 dwarf2reader::DIEHandler *declaration_class_handler
1536 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type, "declarat ion-class");
1537 DeclarationDIE(declaration_class_handler, 0x9ddb35517455ef7aULL,
1538 dwarf2reader::DW_TAG_subprogram, "function-declaration");
1539 declaration_class_handler->Finish();
1540 delete declaration_class_handler;
1541 }
1542 {
1543 dwarf2reader::DIEHandler *definition_class_handler
1544 = StartNamedDIE(&root_handler_, dwarf2reader::DW_TAG_class_type,
1545 "definition-class");
1546 DefinitionDIE(definition_class_handler, dwarf2reader::DW_TAG_subprogram,
1547 0x9ddb35517455ef7aULL, "function-definition",
1548 0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL);
1549 definition_class_handler->Finish();
1550 delete definition_class_handler;
1551 }
1552 root_handler_.Finish();
1553
1554 TestFunctionCount(1);
1555 TestFunction(0, "declaration-class::function-definition",
1556 0xbbd9d54dce3b95b7ULL, 0x39188b7b52b0899fULL);
1557 }
1558
1559 class Errors: public CUFixtureBase, public Test { };
1560
1561 TEST_F(Errors, BadStmtList) {
1562 EXPECT_CALL(reporter_, BadLineInfoOffset(dummy_line_size_ + 10)).Times(1);
1563
1564 ASSERT_TRUE(root_handler_
1565 .StartCompilationUnit(0xc591d5b037543d7cULL, 0x11, 0xcd,
1566 0x2d7d19546cf6590cULL, 3));
1567 dwarf2reader::AttributeList attrs;
1568 attrs.push_back(make_pair(dwarf2reader::DW_AT_name,
1569 dwarf2reader::DW_FORM_strp));
1570 attrs.push_back(make_pair(dwarf2reader::DW_AT_stmt_list,
1571 dwarf2reader::DW_FORM_ref4));
1572 ASSERT_TRUE(root_handler_.StartRootDIE(0xae789dc102cfca54ULL,
1573 dwarf2reader::DW_TAG_compile_unit,
1574 attrs));
1575 root_handler_.ProcessAttributeString(dwarf2reader::DW_AT_name,
1576 dwarf2reader::DW_FORM_strp,
1577 "compilation-unit-name");
1578 root_handler_.ProcessAttributeUnsigned(dwarf2reader::DW_AT_stmt_list,
1579 dwarf2reader::DW_FORM_ref4,
1580 dummy_line_size_ + 10);
1581 root_handler_.EndAttributes();
1582 root_handler_.Finish();
1583 }
1584
1585 TEST_F(Errors, NoLineSection) {
1586 EXPECT_CALL(reporter_, MissingSection(".debug_line")).Times(1);
1587 PushLine(0x88507fb678052611ULL, 0x42c8e9de6bbaa0faULL, "line-file", 64472290);
1588 // Delete the entry for .debug_line added by the fixture class's constructor.
1589 file_context_.section_map.clear();
1590
1591 StartCU();
1592 root_handler_.Finish();
1593 }
1594
1595 TEST_F(Errors, BadDwarfVersion1) {
1596 // Kludge: satisfy reporter_'s expectation.
1597 reporter_.SetCUName("compilation-unit-name");
1598
1599 ASSERT_FALSE(root_handler_
1600 .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
1601 0xc9de224ccb99ac3eULL, 1));
1602 }
1603
1604 TEST_F(Errors, GoodDwarfVersion2) {
1605 // Kludge: satisfy reporter_'s expectation.
1606 reporter_.SetCUName("compilation-unit-name");
1607
1608 ASSERT_TRUE(root_handler_
1609 .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
1610 0xc9de224ccb99ac3eULL, 2));
1611 }
1612
1613 TEST_F(Errors, GoodDwarfVersion3) {
1614 // Kludge: satisfy reporter_'s expectation.
1615 reporter_.SetCUName("compilation-unit-name");
1616
1617 ASSERT_TRUE(root_handler_
1618 .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
1619 0xc9de224ccb99ac3eULL, 3));
1620 }
1621
1622 TEST_F(Errors, BadCURootDIETag) {
1623 // Kludge: satisfy reporter_'s expectation.
1624 reporter_.SetCUName("compilation-unit-name");
1625
1626 ASSERT_TRUE(root_handler_
1627 .StartCompilationUnit(0xadf6e0eb71e2b0d9ULL, 0x4d, 0x90,
1628 0xc9de224ccb99ac3eULL, 3));
1629
1630 dwarf2reader::AttributeList no_attrs;
1631 ASSERT_FALSE(root_handler_.StartRootDIE(0x02e56bfbda9e7337ULL,
1632 dwarf2reader::DW_TAG_subprogram,
1633 no_attrs));
1634 }
1635
1636 // Tests for DwarfCUToModule::Reporter. These just produce (or fail to
1637 // produce) output, so their results need to be checked by hand.
1638 struct Reporter: public Test {
1639 Reporter()
1640 : reporter("filename", 0x123456789abcdef0ULL) {
1641 reporter.SetCUName("compilation-unit-name");
1642
1643 function.name = "function name";
1644 function.address = 0x19c45c30770c1eb0ULL;
1645 function.size = 0x89808a5bdfa0a6a3ULL;
1646 function.parameter_size = 0x6a329f18683dcd51ULL;
1647
1648 file.name = "source file name";
1649
1650 line.address = 0x3606ac6267aebeccULL;
1651 line.size = 0x5de482229f32556aULL;
1652 line.file = &file;
1653 line.number = 93400201;
1654 }
1655
1656 DwarfCUToModule::WarningReporter reporter;
1657 Module::Function function;
1658 Module::File file;
1659 Module::Line line;
1660 };
1661
1662 TEST_F(Reporter, UnknownSpecification) {
1663 reporter.UnknownSpecification(0x123456789abcdef1ULL, 0x323456789abcdef2ULL);
1664 }
1665
1666 TEST_F(Reporter, UnknownAbstractOrigin) {
1667 reporter.UnknownAbstractOrigin(0x123456789abcdef1ULL, 0x323456789abcdef2ULL);
1668 }
1669
1670 TEST_F(Reporter, MissingSection) {
1671 reporter.MissingSection("section name");
1672 }
1673
1674 TEST_F(Reporter, BadLineInfoOffset) {
1675 reporter.BadLineInfoOffset(0x123456789abcdef1ULL);
1676 }
1677
1678 TEST_F(Reporter, UncoveredFunctionDisabled) {
1679 reporter.UncoveredFunction(function);
1680 EXPECT_FALSE(reporter.uncovered_warnings_enabled());
1681 }
1682
1683 TEST_F(Reporter, UncoveredFunctionEnabled) {
1684 reporter.set_uncovered_warnings_enabled(true);
1685 reporter.UncoveredFunction(function);
1686 EXPECT_TRUE(reporter.uncovered_warnings_enabled());
1687 }
1688
1689 TEST_F(Reporter, UncoveredLineDisabled) {
1690 reporter.UncoveredLine(line);
1691 EXPECT_FALSE(reporter.uncovered_warnings_enabled());
1692 }
1693
1694 TEST_F(Reporter, UncoveredLineEnabled) {
1695 reporter.set_uncovered_warnings_enabled(true);
1696 reporter.UncoveredLine(line);
1697 EXPECT_TRUE(reporter.uncovered_warnings_enabled());
1698 }
1699
1700 // Would be nice to also test:
1701 // - overlapping lines, functions
OLDNEW
« no previous file with comments | « obsolete/breakpad/common/dwarf_cu_to_module.cc ('k') | obsolete/breakpad/common/dwarf_line_to_module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698