1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_die_unittest.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,484 @@ 1.4 +// Copyright (c) 2012, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com> 1.34 + 1.35 +// dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit 1.36 + 1.37 +#include <stdlib.h> 1.38 + 1.39 +#include <iostream> 1.40 +#include <string> 1.41 +#include <vector> 1.42 + 1.43 +#include "breakpad_googletest_includes.h" 1.44 +#include "common/dwarf/bytereader-inl.h" 1.45 +#include "common/dwarf/dwarf2reader_test_common.h" 1.46 +#include "common/dwarf/dwarf2reader.h" 1.47 +#include "common/using_std_string.h" 1.48 +#include "google_breakpad/common/breakpad_types.h" 1.49 + 1.50 +using google_breakpad::test_assembler::Endianness; 1.51 +using google_breakpad::test_assembler::Label; 1.52 +using google_breakpad::test_assembler::Section; 1.53 +using google_breakpad::test_assembler::kBigEndian; 1.54 +using google_breakpad::test_assembler::kLittleEndian; 1.55 + 1.56 +using dwarf2reader::ByteReader; 1.57 +using dwarf2reader::CompilationUnit; 1.58 +using dwarf2reader::Dwarf2Handler; 1.59 +using dwarf2reader::DwarfAttribute; 1.60 +using dwarf2reader::DwarfForm; 1.61 +using dwarf2reader::DwarfHasChild; 1.62 +using dwarf2reader::DwarfTag; 1.63 +using dwarf2reader::ENDIANNESS_BIG; 1.64 +using dwarf2reader::ENDIANNESS_LITTLE; 1.65 +using dwarf2reader::SectionMap; 1.66 + 1.67 +using std::vector; 1.68 +using testing::InSequence; 1.69 +using testing::Pointee; 1.70 +using testing::Return; 1.71 +using testing::Sequence; 1.72 +using testing::Test; 1.73 +using testing::TestWithParam; 1.74 +using testing::_; 1.75 + 1.76 +class MockDwarf2Handler: public Dwarf2Handler { 1.77 + public: 1.78 + MOCK_METHOD5(StartCompilationUnit, bool(uint64 offset, uint8 address_size, 1.79 + uint8 offset_size, uint64 cu_length, 1.80 + uint8 dwarf_version)); 1.81 + MOCK_METHOD2(StartDIE, bool(uint64 offset, enum DwarfTag tag)); 1.82 + MOCK_METHOD4(ProcessAttributeUnsigned, void(uint64 offset, 1.83 + DwarfAttribute attr, 1.84 + enum DwarfForm form, 1.85 + uint64 data)); 1.86 + MOCK_METHOD4(ProcessAttributeSigned, void(uint64 offset, 1.87 + enum DwarfAttribute attr, 1.88 + enum DwarfForm form, 1.89 + int64 data)); 1.90 + MOCK_METHOD4(ProcessAttributeReference, void(uint64 offset, 1.91 + enum DwarfAttribute attr, 1.92 + enum DwarfForm form, 1.93 + uint64 data)); 1.94 + MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset, 1.95 + enum DwarfAttribute attr, 1.96 + enum DwarfForm form, 1.97 + const char* data, 1.98 + uint64 len)); 1.99 + MOCK_METHOD4(ProcessAttributeString, void(uint64 offset, 1.100 + enum DwarfAttribute attr, 1.101 + enum DwarfForm form, 1.102 + const string& data)); 1.103 + MOCK_METHOD4(ProcessAttributeSignature, void(uint64 offset, 1.104 + DwarfAttribute attr, 1.105 + enum DwarfForm form, 1.106 + uint64 signature)); 1.107 + MOCK_METHOD1(EndDIE, void(uint64 offset)); 1.108 +}; 1.109 + 1.110 +struct DIEFixture { 1.111 + 1.112 + DIEFixture() { 1.113 + // Fix the initial offset of the .debug_info and .debug_abbrev sections. 1.114 + info.start() = 0; 1.115 + abbrevs.start() = 0; 1.116 + 1.117 + // Default expectations for the data handler. 1.118 + EXPECT_CALL(handler, StartCompilationUnit(_, _, _, _, _)).Times(0); 1.119 + EXPECT_CALL(handler, StartDIE(_, _)).Times(0); 1.120 + EXPECT_CALL(handler, ProcessAttributeUnsigned(_, _, _, _)).Times(0); 1.121 + EXPECT_CALL(handler, ProcessAttributeSigned(_, _, _, _)).Times(0); 1.122 + EXPECT_CALL(handler, ProcessAttributeReference(_, _, _, _)).Times(0); 1.123 + EXPECT_CALL(handler, ProcessAttributeBuffer(_, _, _, _, _)).Times(0); 1.124 + EXPECT_CALL(handler, ProcessAttributeString(_, _, _, _)).Times(0); 1.125 + EXPECT_CALL(handler, EndDIE(_)).Times(0); 1.126 + } 1.127 + 1.128 + // Return a reference to a section map whose .debug_info section refers 1.129 + // to |info|, and whose .debug_abbrev section refers to |abbrevs|. This 1.130 + // function returns a reference to the same SectionMap each time; new 1.131 + // calls wipe out maps established by earlier calls. 1.132 + const SectionMap &MakeSectionMap() { 1.133 + // Copy the sections' contents into strings that will live as long as 1.134 + // the map itself. 1.135 + assert(info.GetContents(&info_contents)); 1.136 + assert(abbrevs.GetContents(&abbrevs_contents)); 1.137 + section_map.clear(); 1.138 + section_map[".debug_info"].first = info_contents.data(); 1.139 + section_map[".debug_info"].second = info_contents.size(); 1.140 + section_map[".debug_abbrev"].first = abbrevs_contents.data(); 1.141 + section_map[".debug_abbrev"].second = abbrevs_contents.size(); 1.142 + return section_map; 1.143 + } 1.144 + 1.145 + TestCompilationUnit info; 1.146 + TestAbbrevTable abbrevs; 1.147 + MockDwarf2Handler handler; 1.148 + string abbrevs_contents, info_contents; 1.149 + SectionMap section_map; 1.150 +}; 1.151 + 1.152 +struct DwarfHeaderParams { 1.153 + DwarfHeaderParams(Endianness endianness, size_t format_size, 1.154 + int version, size_t address_size) 1.155 + : endianness(endianness), format_size(format_size), 1.156 + version(version), address_size(address_size) { } 1.157 + Endianness endianness; 1.158 + size_t format_size; // 4-byte or 8-byte DWARF offsets 1.159 + int version; 1.160 + size_t address_size; 1.161 +}; 1.162 + 1.163 +class DwarfHeader: public DIEFixture, 1.164 + public TestWithParam<DwarfHeaderParams> { }; 1.165 + 1.166 +TEST_P(DwarfHeader, Header) { 1.167 + Label abbrev_table = abbrevs.Here(); 1.168 + abbrevs.Abbrev(1, dwarf2reader::DW_TAG_compile_unit, 1.169 + dwarf2reader::DW_children_yes) 1.170 + .Attribute(dwarf2reader::DW_AT_name, dwarf2reader::DW_FORM_string) 1.171 + .EndAbbrev() 1.172 + .EndTable(); 1.173 + 1.174 + info.set_format_size(GetParam().format_size); 1.175 + info.set_endianness(GetParam().endianness); 1.176 + 1.177 + info.Header(GetParam().version, abbrev_table, GetParam().address_size) 1.178 + .ULEB128(1) // DW_TAG_compile_unit, with children 1.179 + .AppendCString("sam") // DW_AT_name, DW_FORM_string 1.180 + .D8(0); // end of children 1.181 + info.Finish(); 1.182 + 1.183 + { 1.184 + InSequence s; 1.185 + EXPECT_CALL(handler, 1.186 + StartCompilationUnit(0, GetParam().address_size, 1.187 + GetParam().format_size, _, 1.188 + GetParam().version)) 1.189 + .WillOnce(Return(true)); 1.190 + EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit)) 1.191 + .WillOnce(Return(true)); 1.192 + EXPECT_CALL(handler, ProcessAttributeString(_, dwarf2reader::DW_AT_name, 1.193 + dwarf2reader::DW_FORM_string, 1.194 + "sam")) 1.195 + .WillOnce(Return()); 1.196 + EXPECT_CALL(handler, EndDIE(_)) 1.197 + .WillOnce(Return()); 1.198 + } 1.199 + 1.200 + ByteReader byte_reader(GetParam().endianness == kLittleEndian ? 1.201 + ENDIANNESS_LITTLE : ENDIANNESS_BIG); 1.202 + CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler); 1.203 + EXPECT_EQ(parser.Start(), info_contents.size()); 1.204 +} 1.205 + 1.206 +INSTANTIATE_TEST_CASE_P( 1.207 + HeaderVariants, DwarfHeader, 1.208 + ::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4), 1.209 + DwarfHeaderParams(kLittleEndian, 4, 2, 8), 1.210 + DwarfHeaderParams(kLittleEndian, 4, 3, 4), 1.211 + DwarfHeaderParams(kLittleEndian, 4, 3, 8), 1.212 + DwarfHeaderParams(kLittleEndian, 4, 4, 4), 1.213 + DwarfHeaderParams(kLittleEndian, 4, 4, 8), 1.214 + DwarfHeaderParams(kLittleEndian, 8, 2, 4), 1.215 + DwarfHeaderParams(kLittleEndian, 8, 2, 8), 1.216 + DwarfHeaderParams(kLittleEndian, 8, 3, 4), 1.217 + DwarfHeaderParams(kLittleEndian, 8, 3, 8), 1.218 + DwarfHeaderParams(kLittleEndian, 8, 4, 4), 1.219 + DwarfHeaderParams(kLittleEndian, 8, 4, 8), 1.220 + DwarfHeaderParams(kBigEndian, 4, 2, 4), 1.221 + DwarfHeaderParams(kBigEndian, 4, 2, 8), 1.222 + DwarfHeaderParams(kBigEndian, 4, 3, 4), 1.223 + DwarfHeaderParams(kBigEndian, 4, 3, 8), 1.224 + DwarfHeaderParams(kBigEndian, 4, 4, 4), 1.225 + DwarfHeaderParams(kBigEndian, 4, 4, 8), 1.226 + DwarfHeaderParams(kBigEndian, 8, 2, 4), 1.227 + DwarfHeaderParams(kBigEndian, 8, 2, 8), 1.228 + DwarfHeaderParams(kBigEndian, 8, 3, 4), 1.229 + DwarfHeaderParams(kBigEndian, 8, 3, 8), 1.230 + DwarfHeaderParams(kBigEndian, 8, 4, 4), 1.231 + DwarfHeaderParams(kBigEndian, 8, 4, 8))); 1.232 + 1.233 +struct DwarfFormsFixture: public DIEFixture { 1.234 + // Start a compilation unit, as directed by |params|, containing one 1.235 + // childless DIE of the given tag, with one attribute of the given name 1.236 + // and form. The 'info' fixture member is left just after the abbrev 1.237 + // code, waiting for the attribute value to be appended. 1.238 + void StartSingleAttributeDIE(const DwarfHeaderParams ¶ms, 1.239 + DwarfTag tag, DwarfAttribute name, 1.240 + DwarfForm form) { 1.241 + // Create the abbreviation table. 1.242 + Label abbrev_table = abbrevs.Here(); 1.243 + abbrevs.Abbrev(1, tag, dwarf2reader::DW_children_no) 1.244 + .Attribute(name, form) 1.245 + .EndAbbrev() 1.246 + .EndTable(); 1.247 + 1.248 + // Create the compilation unit, up to the attribute value. 1.249 + info.set_format_size(params.format_size); 1.250 + info.set_endianness(params.endianness); 1.251 + info.Header(params.version, abbrev_table, params.address_size) 1.252 + .ULEB128(1); // abbrev code 1.253 + } 1.254 + 1.255 + // Set up handler to expect a compilation unit matching |params|, 1.256 + // containing one childless DIE of the given tag, in the sequence s. Stop 1.257 + // just before the expectations. 1.258 + void ExpectBeginCompilationUnit(const DwarfHeaderParams ¶ms, 1.259 + DwarfTag tag, uint64 offset=0) { 1.260 + EXPECT_CALL(handler, 1.261 + StartCompilationUnit(offset, params.address_size, 1.262 + params.format_size, _, 1.263 + params.version)) 1.264 + .InSequence(s) 1.265 + .WillOnce(Return(true)); 1.266 + EXPECT_CALL(handler, StartDIE(_, tag)) 1.267 + .InSequence(s) 1.268 + .WillOnce(Return(true)); 1.269 + } 1.270 + 1.271 + void ExpectEndCompilationUnit() { 1.272 + EXPECT_CALL(handler, EndDIE(_)) 1.273 + .InSequence(s) 1.274 + .WillOnce(Return()); 1.275 + } 1.276 + 1.277 + void ParseCompilationUnit(const DwarfHeaderParams ¶ms, uint64 offset=0) { 1.278 + ByteReader byte_reader(params.endianness == kLittleEndian ? 1.279 + ENDIANNESS_LITTLE : ENDIANNESS_BIG); 1.280 + CompilationUnit parser(MakeSectionMap(), offset, &byte_reader, &handler); 1.281 + EXPECT_EQ(offset + parser.Start(), info_contents.size()); 1.282 + } 1.283 + 1.284 + // The sequence to which the fixture's methods append expectations. 1.285 + Sequence s; 1.286 +}; 1.287 + 1.288 +struct DwarfForms: public DwarfFormsFixture, 1.289 + public TestWithParam<DwarfHeaderParams> { }; 1.290 + 1.291 +TEST_P(DwarfForms, addr) { 1.292 + StartSingleAttributeDIE(GetParam(), dwarf2reader::DW_TAG_compile_unit, 1.293 + dwarf2reader::DW_AT_low_pc, 1.294 + dwarf2reader::DW_FORM_addr); 1.295 + uint64_t value; 1.296 + if (GetParam().address_size == 4) { 1.297 + value = 0xc8e9ffcc; 1.298 + info.D32(value); 1.299 + } else { 1.300 + value = 0xe942517fc2768564ULL; 1.301 + info.D64(value); 1.302 + } 1.303 + info.Finish(); 1.304 + 1.305 + ExpectBeginCompilationUnit(GetParam(), dwarf2reader::DW_TAG_compile_unit); 1.306 + EXPECT_CALL(handler, ProcessAttributeUnsigned(_, dwarf2reader::DW_AT_low_pc, 1.307 + dwarf2reader::DW_FORM_addr, 1.308 + value)) 1.309 + .InSequence(s) 1.310 + .WillOnce(Return()); 1.311 + ExpectEndCompilationUnit(); 1.312 + 1.313 + ParseCompilationUnit(GetParam()); 1.314 +} 1.315 + 1.316 +TEST_P(DwarfForms, block2_empty) { 1.317 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7, 1.318 + (DwarfAttribute) 0xe52c4463, 1.319 + dwarf2reader::DW_FORM_block2); 1.320 + info.D16(0); 1.321 + info.Finish(); 1.322 + 1.323 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7); 1.324 + EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463, 1.325 + dwarf2reader::DW_FORM_block2, 1.326 + _, 0)) 1.327 + .InSequence(s) 1.328 + .WillOnce(Return()); 1.329 + ExpectEndCompilationUnit(); 1.330 + 1.331 + ParseCompilationUnit(GetParam()); 1.332 +} 1.333 + 1.334 +TEST_P(DwarfForms, block2) { 1.335 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7, 1.336 + (DwarfAttribute) 0xe52c4463, 1.337 + dwarf2reader::DW_FORM_block2); 1.338 + unsigned char data[258]; 1.339 + memset(data, '*', sizeof(data)); 1.340 + info.D16(sizeof(data)) 1.341 + .Append(data, sizeof(data)); 1.342 + info.Finish(); 1.343 + 1.344 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7); 1.345 + EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463, 1.346 + dwarf2reader::DW_FORM_block2, 1.347 + Pointee('*'), 258)) 1.348 + .InSequence(s) 1.349 + .WillOnce(Return()); 1.350 + ExpectEndCompilationUnit(); 1.351 + 1.352 + ParseCompilationUnit(GetParam()); 1.353 +} 1.354 + 1.355 +TEST_P(DwarfForms, flag_present) { 1.356 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x3e449ac2, 1.357 + (DwarfAttribute) 0x359d1972, 1.358 + dwarf2reader::DW_FORM_flag_present); 1.359 + // DW_FORM_flag_present occupies no space in the DIE. 1.360 + info.Finish(); 1.361 + 1.362 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x3e449ac2); 1.363 + EXPECT_CALL(handler, 1.364 + ProcessAttributeUnsigned(_, (DwarfAttribute) 0x359d1972, 1.365 + dwarf2reader::DW_FORM_flag_present, 1.366 + 1)) 1.367 + .InSequence(s) 1.368 + .WillOnce(Return()); 1.369 + ExpectEndCompilationUnit(); 1.370 + 1.371 + ParseCompilationUnit(GetParam()); 1.372 +} 1.373 + 1.374 +TEST_P(DwarfForms, sec_offset) { 1.375 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x1d971689, 1.376 + (DwarfAttribute) 0xa060bfd1, 1.377 + dwarf2reader::DW_FORM_sec_offset); 1.378 + uint64_t value; 1.379 + if (GetParam().format_size == 4) { 1.380 + value = 0xacc9c388; 1.381 + info.D32(value); 1.382 + } else { 1.383 + value = 0xcffe5696ffe3ed0aULL; 1.384 + info.D64(value); 1.385 + } 1.386 + info.Finish(); 1.387 + 1.388 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x1d971689); 1.389 + EXPECT_CALL(handler, ProcessAttributeUnsigned(_, (DwarfAttribute) 0xa060bfd1, 1.390 + dwarf2reader::DW_FORM_sec_offset, 1.391 + value)) 1.392 + .InSequence(s) 1.393 + .WillOnce(Return()); 1.394 + ExpectEndCompilationUnit(); 1.395 + 1.396 + ParseCompilationUnit(GetParam()); 1.397 +} 1.398 + 1.399 +TEST_P(DwarfForms, exprloc) { 1.400 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0xb6d167bb, 1.401 + (DwarfAttribute) 0xba3ae5cb, 1.402 + dwarf2reader::DW_FORM_exprloc); 1.403 + info.ULEB128(29) 1.404 + .Append(29, 173); 1.405 + info.Finish(); 1.406 + 1.407 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0xb6d167bb); 1.408 + EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xba3ae5cb, 1.409 + dwarf2reader::DW_FORM_exprloc, 1.410 + Pointee(173), 29)) 1.411 + .InSequence(s) 1.412 + .WillOnce(Return()); 1.413 + ExpectEndCompilationUnit(); 1.414 + 1.415 + ParseCompilationUnit(GetParam()); 1.416 +} 1.417 + 1.418 +TEST_P(DwarfForms, ref_sig8) { 1.419 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b, 1.420 + (DwarfAttribute) 0xd708d908, 1.421 + dwarf2reader::DW_FORM_ref_sig8); 1.422 + info.D64(0xf72fa0cb6ddcf9d6ULL); 1.423 + info.Finish(); 1.424 + 1.425 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b); 1.426 + EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908, 1.427 + dwarf2reader::DW_FORM_ref_sig8, 1.428 + 0xf72fa0cb6ddcf9d6ULL)) 1.429 + .InSequence(s) 1.430 + .WillOnce(Return()); 1.431 + ExpectEndCompilationUnit(); 1.432 + 1.433 + ParseCompilationUnit(GetParam()); 1.434 +} 1.435 + 1.436 +// A value passed to ProcessAttributeSignature is just an absolute number, 1.437 +// not an offset within the compilation unit as most of the other 1.438 +// DW_FORM_ref forms are. Check that the reader doesn't try to apply any 1.439 +// offset to the signature, by reading it from a compilation unit that does 1.440 +// not start at the beginning of the section. 1.441 +TEST_P(DwarfForms, ref_sig8_not_first) { 1.442 + info.Append(98, '*'); 1.443 + StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b, 1.444 + (DwarfAttribute) 0xd708d908, 1.445 + dwarf2reader::DW_FORM_ref_sig8); 1.446 + info.D64(0xf72fa0cb6ddcf9d6ULL); 1.447 + info.Finish(); 1.448 + 1.449 + ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b, 98); 1.450 + EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908, 1.451 + dwarf2reader::DW_FORM_ref_sig8, 1.452 + 0xf72fa0cb6ddcf9d6ULL)) 1.453 + .InSequence(s) 1.454 + .WillOnce(Return()); 1.455 + ExpectEndCompilationUnit(); 1.456 + 1.457 + ParseCompilationUnit(GetParam(), 98); 1.458 +} 1.459 + 1.460 +// Tests for the other attribute forms could go here. 1.461 + 1.462 +INSTANTIATE_TEST_CASE_P( 1.463 + HeaderVariants, DwarfForms, 1.464 + ::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4), 1.465 + DwarfHeaderParams(kLittleEndian, 4, 2, 8), 1.466 + DwarfHeaderParams(kLittleEndian, 4, 3, 4), 1.467 + DwarfHeaderParams(kLittleEndian, 4, 3, 8), 1.468 + DwarfHeaderParams(kLittleEndian, 4, 4, 4), 1.469 + DwarfHeaderParams(kLittleEndian, 4, 4, 8), 1.470 + DwarfHeaderParams(kLittleEndian, 8, 2, 4), 1.471 + DwarfHeaderParams(kLittleEndian, 8, 2, 8), 1.472 + DwarfHeaderParams(kLittleEndian, 8, 3, 4), 1.473 + DwarfHeaderParams(kLittleEndian, 8, 3, 8), 1.474 + DwarfHeaderParams(kLittleEndian, 8, 4, 4), 1.475 + DwarfHeaderParams(kLittleEndian, 8, 4, 8), 1.476 + DwarfHeaderParams(kBigEndian, 4, 2, 4), 1.477 + DwarfHeaderParams(kBigEndian, 4, 2, 8), 1.478 + DwarfHeaderParams(kBigEndian, 4, 3, 4), 1.479 + DwarfHeaderParams(kBigEndian, 4, 3, 8), 1.480 + DwarfHeaderParams(kBigEndian, 4, 4, 4), 1.481 + DwarfHeaderParams(kBigEndian, 4, 4, 8), 1.482 + DwarfHeaderParams(kBigEndian, 8, 2, 4), 1.483 + DwarfHeaderParams(kBigEndian, 8, 2, 8), 1.484 + DwarfHeaderParams(kBigEndian, 8, 3, 4), 1.485 + DwarfHeaderParams(kBigEndian, 8, 3, 8), 1.486 + DwarfHeaderParams(kBigEndian, 8, 4, 4), 1.487 + DwarfHeaderParams(kBigEndian, 8, 4, 8)));