toolkit/crashreporter/google-breakpad/src/common/dwarf/dwarf2reader_die_unittest.cc

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 // Copyright (c) 2012, Google Inc.
michael@0 2 // All rights reserved.
michael@0 3 //
michael@0 4 // Redistribution and use in source and binary forms, with or without
michael@0 5 // modification, are permitted provided that the following conditions are
michael@0 6 // met:
michael@0 7 //
michael@0 8 // * Redistributions of source code must retain the above copyright
michael@0 9 // notice, this list of conditions and the following disclaimer.
michael@0 10 // * Redistributions in binary form must reproduce the above
michael@0 11 // copyright notice, this list of conditions and the following disclaimer
michael@0 12 // in the documentation and/or other materials provided with the
michael@0 13 // distribution.
michael@0 14 // * Neither the name of Google Inc. nor the names of its
michael@0 15 // contributors may be used to endorse or promote products derived from
michael@0 16 // this software without specific prior written permission.
michael@0 17 //
michael@0 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 29
michael@0 30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
michael@0 31
michael@0 32 // dwarf2reader_die_unittest.cc: Unit tests for dwarf2reader::CompilationUnit
michael@0 33
michael@0 34 #include <stdlib.h>
michael@0 35
michael@0 36 #include <iostream>
michael@0 37 #include <string>
michael@0 38 #include <vector>
michael@0 39
michael@0 40 #include "breakpad_googletest_includes.h"
michael@0 41 #include "common/dwarf/bytereader-inl.h"
michael@0 42 #include "common/dwarf/dwarf2reader_test_common.h"
michael@0 43 #include "common/dwarf/dwarf2reader.h"
michael@0 44 #include "common/using_std_string.h"
michael@0 45 #include "google_breakpad/common/breakpad_types.h"
michael@0 46
michael@0 47 using google_breakpad::test_assembler::Endianness;
michael@0 48 using google_breakpad::test_assembler::Label;
michael@0 49 using google_breakpad::test_assembler::Section;
michael@0 50 using google_breakpad::test_assembler::kBigEndian;
michael@0 51 using google_breakpad::test_assembler::kLittleEndian;
michael@0 52
michael@0 53 using dwarf2reader::ByteReader;
michael@0 54 using dwarf2reader::CompilationUnit;
michael@0 55 using dwarf2reader::Dwarf2Handler;
michael@0 56 using dwarf2reader::DwarfAttribute;
michael@0 57 using dwarf2reader::DwarfForm;
michael@0 58 using dwarf2reader::DwarfHasChild;
michael@0 59 using dwarf2reader::DwarfTag;
michael@0 60 using dwarf2reader::ENDIANNESS_BIG;
michael@0 61 using dwarf2reader::ENDIANNESS_LITTLE;
michael@0 62 using dwarf2reader::SectionMap;
michael@0 63
michael@0 64 using std::vector;
michael@0 65 using testing::InSequence;
michael@0 66 using testing::Pointee;
michael@0 67 using testing::Return;
michael@0 68 using testing::Sequence;
michael@0 69 using testing::Test;
michael@0 70 using testing::TestWithParam;
michael@0 71 using testing::_;
michael@0 72
michael@0 73 class MockDwarf2Handler: public Dwarf2Handler {
michael@0 74 public:
michael@0 75 MOCK_METHOD5(StartCompilationUnit, bool(uint64 offset, uint8 address_size,
michael@0 76 uint8 offset_size, uint64 cu_length,
michael@0 77 uint8 dwarf_version));
michael@0 78 MOCK_METHOD2(StartDIE, bool(uint64 offset, enum DwarfTag tag));
michael@0 79 MOCK_METHOD4(ProcessAttributeUnsigned, void(uint64 offset,
michael@0 80 DwarfAttribute attr,
michael@0 81 enum DwarfForm form,
michael@0 82 uint64 data));
michael@0 83 MOCK_METHOD4(ProcessAttributeSigned, void(uint64 offset,
michael@0 84 enum DwarfAttribute attr,
michael@0 85 enum DwarfForm form,
michael@0 86 int64 data));
michael@0 87 MOCK_METHOD4(ProcessAttributeReference, void(uint64 offset,
michael@0 88 enum DwarfAttribute attr,
michael@0 89 enum DwarfForm form,
michael@0 90 uint64 data));
michael@0 91 MOCK_METHOD5(ProcessAttributeBuffer, void(uint64 offset,
michael@0 92 enum DwarfAttribute attr,
michael@0 93 enum DwarfForm form,
michael@0 94 const char* data,
michael@0 95 uint64 len));
michael@0 96 MOCK_METHOD4(ProcessAttributeString, void(uint64 offset,
michael@0 97 enum DwarfAttribute attr,
michael@0 98 enum DwarfForm form,
michael@0 99 const string& data));
michael@0 100 MOCK_METHOD4(ProcessAttributeSignature, void(uint64 offset,
michael@0 101 DwarfAttribute attr,
michael@0 102 enum DwarfForm form,
michael@0 103 uint64 signature));
michael@0 104 MOCK_METHOD1(EndDIE, void(uint64 offset));
michael@0 105 };
michael@0 106
michael@0 107 struct DIEFixture {
michael@0 108
michael@0 109 DIEFixture() {
michael@0 110 // Fix the initial offset of the .debug_info and .debug_abbrev sections.
michael@0 111 info.start() = 0;
michael@0 112 abbrevs.start() = 0;
michael@0 113
michael@0 114 // Default expectations for the data handler.
michael@0 115 EXPECT_CALL(handler, StartCompilationUnit(_, _, _, _, _)).Times(0);
michael@0 116 EXPECT_CALL(handler, StartDIE(_, _)).Times(0);
michael@0 117 EXPECT_CALL(handler, ProcessAttributeUnsigned(_, _, _, _)).Times(0);
michael@0 118 EXPECT_CALL(handler, ProcessAttributeSigned(_, _, _, _)).Times(0);
michael@0 119 EXPECT_CALL(handler, ProcessAttributeReference(_, _, _, _)).Times(0);
michael@0 120 EXPECT_CALL(handler, ProcessAttributeBuffer(_, _, _, _, _)).Times(0);
michael@0 121 EXPECT_CALL(handler, ProcessAttributeString(_, _, _, _)).Times(0);
michael@0 122 EXPECT_CALL(handler, EndDIE(_)).Times(0);
michael@0 123 }
michael@0 124
michael@0 125 // Return a reference to a section map whose .debug_info section refers
michael@0 126 // to |info|, and whose .debug_abbrev section refers to |abbrevs|. This
michael@0 127 // function returns a reference to the same SectionMap each time; new
michael@0 128 // calls wipe out maps established by earlier calls.
michael@0 129 const SectionMap &MakeSectionMap() {
michael@0 130 // Copy the sections' contents into strings that will live as long as
michael@0 131 // the map itself.
michael@0 132 assert(info.GetContents(&info_contents));
michael@0 133 assert(abbrevs.GetContents(&abbrevs_contents));
michael@0 134 section_map.clear();
michael@0 135 section_map[".debug_info"].first = info_contents.data();
michael@0 136 section_map[".debug_info"].second = info_contents.size();
michael@0 137 section_map[".debug_abbrev"].first = abbrevs_contents.data();
michael@0 138 section_map[".debug_abbrev"].second = abbrevs_contents.size();
michael@0 139 return section_map;
michael@0 140 }
michael@0 141
michael@0 142 TestCompilationUnit info;
michael@0 143 TestAbbrevTable abbrevs;
michael@0 144 MockDwarf2Handler handler;
michael@0 145 string abbrevs_contents, info_contents;
michael@0 146 SectionMap section_map;
michael@0 147 };
michael@0 148
michael@0 149 struct DwarfHeaderParams {
michael@0 150 DwarfHeaderParams(Endianness endianness, size_t format_size,
michael@0 151 int version, size_t address_size)
michael@0 152 : endianness(endianness), format_size(format_size),
michael@0 153 version(version), address_size(address_size) { }
michael@0 154 Endianness endianness;
michael@0 155 size_t format_size; // 4-byte or 8-byte DWARF offsets
michael@0 156 int version;
michael@0 157 size_t address_size;
michael@0 158 };
michael@0 159
michael@0 160 class DwarfHeader: public DIEFixture,
michael@0 161 public TestWithParam<DwarfHeaderParams> { };
michael@0 162
michael@0 163 TEST_P(DwarfHeader, Header) {
michael@0 164 Label abbrev_table = abbrevs.Here();
michael@0 165 abbrevs.Abbrev(1, dwarf2reader::DW_TAG_compile_unit,
michael@0 166 dwarf2reader::DW_children_yes)
michael@0 167 .Attribute(dwarf2reader::DW_AT_name, dwarf2reader::DW_FORM_string)
michael@0 168 .EndAbbrev()
michael@0 169 .EndTable();
michael@0 170
michael@0 171 info.set_format_size(GetParam().format_size);
michael@0 172 info.set_endianness(GetParam().endianness);
michael@0 173
michael@0 174 info.Header(GetParam().version, abbrev_table, GetParam().address_size)
michael@0 175 .ULEB128(1) // DW_TAG_compile_unit, with children
michael@0 176 .AppendCString("sam") // DW_AT_name, DW_FORM_string
michael@0 177 .D8(0); // end of children
michael@0 178 info.Finish();
michael@0 179
michael@0 180 {
michael@0 181 InSequence s;
michael@0 182 EXPECT_CALL(handler,
michael@0 183 StartCompilationUnit(0, GetParam().address_size,
michael@0 184 GetParam().format_size, _,
michael@0 185 GetParam().version))
michael@0 186 .WillOnce(Return(true));
michael@0 187 EXPECT_CALL(handler, StartDIE(_, dwarf2reader::DW_TAG_compile_unit))
michael@0 188 .WillOnce(Return(true));
michael@0 189 EXPECT_CALL(handler, ProcessAttributeString(_, dwarf2reader::DW_AT_name,
michael@0 190 dwarf2reader::DW_FORM_string,
michael@0 191 "sam"))
michael@0 192 .WillOnce(Return());
michael@0 193 EXPECT_CALL(handler, EndDIE(_))
michael@0 194 .WillOnce(Return());
michael@0 195 }
michael@0 196
michael@0 197 ByteReader byte_reader(GetParam().endianness == kLittleEndian ?
michael@0 198 ENDIANNESS_LITTLE : ENDIANNESS_BIG);
michael@0 199 CompilationUnit parser(MakeSectionMap(), 0, &byte_reader, &handler);
michael@0 200 EXPECT_EQ(parser.Start(), info_contents.size());
michael@0 201 }
michael@0 202
michael@0 203 INSTANTIATE_TEST_CASE_P(
michael@0 204 HeaderVariants, DwarfHeader,
michael@0 205 ::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4),
michael@0 206 DwarfHeaderParams(kLittleEndian, 4, 2, 8),
michael@0 207 DwarfHeaderParams(kLittleEndian, 4, 3, 4),
michael@0 208 DwarfHeaderParams(kLittleEndian, 4, 3, 8),
michael@0 209 DwarfHeaderParams(kLittleEndian, 4, 4, 4),
michael@0 210 DwarfHeaderParams(kLittleEndian, 4, 4, 8),
michael@0 211 DwarfHeaderParams(kLittleEndian, 8, 2, 4),
michael@0 212 DwarfHeaderParams(kLittleEndian, 8, 2, 8),
michael@0 213 DwarfHeaderParams(kLittleEndian, 8, 3, 4),
michael@0 214 DwarfHeaderParams(kLittleEndian, 8, 3, 8),
michael@0 215 DwarfHeaderParams(kLittleEndian, 8, 4, 4),
michael@0 216 DwarfHeaderParams(kLittleEndian, 8, 4, 8),
michael@0 217 DwarfHeaderParams(kBigEndian, 4, 2, 4),
michael@0 218 DwarfHeaderParams(kBigEndian, 4, 2, 8),
michael@0 219 DwarfHeaderParams(kBigEndian, 4, 3, 4),
michael@0 220 DwarfHeaderParams(kBigEndian, 4, 3, 8),
michael@0 221 DwarfHeaderParams(kBigEndian, 4, 4, 4),
michael@0 222 DwarfHeaderParams(kBigEndian, 4, 4, 8),
michael@0 223 DwarfHeaderParams(kBigEndian, 8, 2, 4),
michael@0 224 DwarfHeaderParams(kBigEndian, 8, 2, 8),
michael@0 225 DwarfHeaderParams(kBigEndian, 8, 3, 4),
michael@0 226 DwarfHeaderParams(kBigEndian, 8, 3, 8),
michael@0 227 DwarfHeaderParams(kBigEndian, 8, 4, 4),
michael@0 228 DwarfHeaderParams(kBigEndian, 8, 4, 8)));
michael@0 229
michael@0 230 struct DwarfFormsFixture: public DIEFixture {
michael@0 231 // Start a compilation unit, as directed by |params|, containing one
michael@0 232 // childless DIE of the given tag, with one attribute of the given name
michael@0 233 // and form. The 'info' fixture member is left just after the abbrev
michael@0 234 // code, waiting for the attribute value to be appended.
michael@0 235 void StartSingleAttributeDIE(const DwarfHeaderParams &params,
michael@0 236 DwarfTag tag, DwarfAttribute name,
michael@0 237 DwarfForm form) {
michael@0 238 // Create the abbreviation table.
michael@0 239 Label abbrev_table = abbrevs.Here();
michael@0 240 abbrevs.Abbrev(1, tag, dwarf2reader::DW_children_no)
michael@0 241 .Attribute(name, form)
michael@0 242 .EndAbbrev()
michael@0 243 .EndTable();
michael@0 244
michael@0 245 // Create the compilation unit, up to the attribute value.
michael@0 246 info.set_format_size(params.format_size);
michael@0 247 info.set_endianness(params.endianness);
michael@0 248 info.Header(params.version, abbrev_table, params.address_size)
michael@0 249 .ULEB128(1); // abbrev code
michael@0 250 }
michael@0 251
michael@0 252 // Set up handler to expect a compilation unit matching |params|,
michael@0 253 // containing one childless DIE of the given tag, in the sequence s. Stop
michael@0 254 // just before the expectations.
michael@0 255 void ExpectBeginCompilationUnit(const DwarfHeaderParams &params,
michael@0 256 DwarfTag tag, uint64 offset=0) {
michael@0 257 EXPECT_CALL(handler,
michael@0 258 StartCompilationUnit(offset, params.address_size,
michael@0 259 params.format_size, _,
michael@0 260 params.version))
michael@0 261 .InSequence(s)
michael@0 262 .WillOnce(Return(true));
michael@0 263 EXPECT_CALL(handler, StartDIE(_, tag))
michael@0 264 .InSequence(s)
michael@0 265 .WillOnce(Return(true));
michael@0 266 }
michael@0 267
michael@0 268 void ExpectEndCompilationUnit() {
michael@0 269 EXPECT_CALL(handler, EndDIE(_))
michael@0 270 .InSequence(s)
michael@0 271 .WillOnce(Return());
michael@0 272 }
michael@0 273
michael@0 274 void ParseCompilationUnit(const DwarfHeaderParams &params, uint64 offset=0) {
michael@0 275 ByteReader byte_reader(params.endianness == kLittleEndian ?
michael@0 276 ENDIANNESS_LITTLE : ENDIANNESS_BIG);
michael@0 277 CompilationUnit parser(MakeSectionMap(), offset, &byte_reader, &handler);
michael@0 278 EXPECT_EQ(offset + parser.Start(), info_contents.size());
michael@0 279 }
michael@0 280
michael@0 281 // The sequence to which the fixture's methods append expectations.
michael@0 282 Sequence s;
michael@0 283 };
michael@0 284
michael@0 285 struct DwarfForms: public DwarfFormsFixture,
michael@0 286 public TestWithParam<DwarfHeaderParams> { };
michael@0 287
michael@0 288 TEST_P(DwarfForms, addr) {
michael@0 289 StartSingleAttributeDIE(GetParam(), dwarf2reader::DW_TAG_compile_unit,
michael@0 290 dwarf2reader::DW_AT_low_pc,
michael@0 291 dwarf2reader::DW_FORM_addr);
michael@0 292 uint64_t value;
michael@0 293 if (GetParam().address_size == 4) {
michael@0 294 value = 0xc8e9ffcc;
michael@0 295 info.D32(value);
michael@0 296 } else {
michael@0 297 value = 0xe942517fc2768564ULL;
michael@0 298 info.D64(value);
michael@0 299 }
michael@0 300 info.Finish();
michael@0 301
michael@0 302 ExpectBeginCompilationUnit(GetParam(), dwarf2reader::DW_TAG_compile_unit);
michael@0 303 EXPECT_CALL(handler, ProcessAttributeUnsigned(_, dwarf2reader::DW_AT_low_pc,
michael@0 304 dwarf2reader::DW_FORM_addr,
michael@0 305 value))
michael@0 306 .InSequence(s)
michael@0 307 .WillOnce(Return());
michael@0 308 ExpectEndCompilationUnit();
michael@0 309
michael@0 310 ParseCompilationUnit(GetParam());
michael@0 311 }
michael@0 312
michael@0 313 TEST_P(DwarfForms, block2_empty) {
michael@0 314 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7,
michael@0 315 (DwarfAttribute) 0xe52c4463,
michael@0 316 dwarf2reader::DW_FORM_block2);
michael@0 317 info.D16(0);
michael@0 318 info.Finish();
michael@0 319
michael@0 320 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7);
michael@0 321 EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463,
michael@0 322 dwarf2reader::DW_FORM_block2,
michael@0 323 _, 0))
michael@0 324 .InSequence(s)
michael@0 325 .WillOnce(Return());
michael@0 326 ExpectEndCompilationUnit();
michael@0 327
michael@0 328 ParseCompilationUnit(GetParam());
michael@0 329 }
michael@0 330
michael@0 331 TEST_P(DwarfForms, block2) {
michael@0 332 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x16e4d2f7,
michael@0 333 (DwarfAttribute) 0xe52c4463,
michael@0 334 dwarf2reader::DW_FORM_block2);
michael@0 335 unsigned char data[258];
michael@0 336 memset(data, '*', sizeof(data));
michael@0 337 info.D16(sizeof(data))
michael@0 338 .Append(data, sizeof(data));
michael@0 339 info.Finish();
michael@0 340
michael@0 341 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x16e4d2f7);
michael@0 342 EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xe52c4463,
michael@0 343 dwarf2reader::DW_FORM_block2,
michael@0 344 Pointee('*'), 258))
michael@0 345 .InSequence(s)
michael@0 346 .WillOnce(Return());
michael@0 347 ExpectEndCompilationUnit();
michael@0 348
michael@0 349 ParseCompilationUnit(GetParam());
michael@0 350 }
michael@0 351
michael@0 352 TEST_P(DwarfForms, flag_present) {
michael@0 353 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x3e449ac2,
michael@0 354 (DwarfAttribute) 0x359d1972,
michael@0 355 dwarf2reader::DW_FORM_flag_present);
michael@0 356 // DW_FORM_flag_present occupies no space in the DIE.
michael@0 357 info.Finish();
michael@0 358
michael@0 359 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x3e449ac2);
michael@0 360 EXPECT_CALL(handler,
michael@0 361 ProcessAttributeUnsigned(_, (DwarfAttribute) 0x359d1972,
michael@0 362 dwarf2reader::DW_FORM_flag_present,
michael@0 363 1))
michael@0 364 .InSequence(s)
michael@0 365 .WillOnce(Return());
michael@0 366 ExpectEndCompilationUnit();
michael@0 367
michael@0 368 ParseCompilationUnit(GetParam());
michael@0 369 }
michael@0 370
michael@0 371 TEST_P(DwarfForms, sec_offset) {
michael@0 372 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x1d971689,
michael@0 373 (DwarfAttribute) 0xa060bfd1,
michael@0 374 dwarf2reader::DW_FORM_sec_offset);
michael@0 375 uint64_t value;
michael@0 376 if (GetParam().format_size == 4) {
michael@0 377 value = 0xacc9c388;
michael@0 378 info.D32(value);
michael@0 379 } else {
michael@0 380 value = 0xcffe5696ffe3ed0aULL;
michael@0 381 info.D64(value);
michael@0 382 }
michael@0 383 info.Finish();
michael@0 384
michael@0 385 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x1d971689);
michael@0 386 EXPECT_CALL(handler, ProcessAttributeUnsigned(_, (DwarfAttribute) 0xa060bfd1,
michael@0 387 dwarf2reader::DW_FORM_sec_offset,
michael@0 388 value))
michael@0 389 .InSequence(s)
michael@0 390 .WillOnce(Return());
michael@0 391 ExpectEndCompilationUnit();
michael@0 392
michael@0 393 ParseCompilationUnit(GetParam());
michael@0 394 }
michael@0 395
michael@0 396 TEST_P(DwarfForms, exprloc) {
michael@0 397 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0xb6d167bb,
michael@0 398 (DwarfAttribute) 0xba3ae5cb,
michael@0 399 dwarf2reader::DW_FORM_exprloc);
michael@0 400 info.ULEB128(29)
michael@0 401 .Append(29, 173);
michael@0 402 info.Finish();
michael@0 403
michael@0 404 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0xb6d167bb);
michael@0 405 EXPECT_CALL(handler, ProcessAttributeBuffer(_, (DwarfAttribute) 0xba3ae5cb,
michael@0 406 dwarf2reader::DW_FORM_exprloc,
michael@0 407 Pointee(173), 29))
michael@0 408 .InSequence(s)
michael@0 409 .WillOnce(Return());
michael@0 410 ExpectEndCompilationUnit();
michael@0 411
michael@0 412 ParseCompilationUnit(GetParam());
michael@0 413 }
michael@0 414
michael@0 415 TEST_P(DwarfForms, ref_sig8) {
michael@0 416 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b,
michael@0 417 (DwarfAttribute) 0xd708d908,
michael@0 418 dwarf2reader::DW_FORM_ref_sig8);
michael@0 419 info.D64(0xf72fa0cb6ddcf9d6ULL);
michael@0 420 info.Finish();
michael@0 421
michael@0 422 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b);
michael@0 423 EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908,
michael@0 424 dwarf2reader::DW_FORM_ref_sig8,
michael@0 425 0xf72fa0cb6ddcf9d6ULL))
michael@0 426 .InSequence(s)
michael@0 427 .WillOnce(Return());
michael@0 428 ExpectEndCompilationUnit();
michael@0 429
michael@0 430 ParseCompilationUnit(GetParam());
michael@0 431 }
michael@0 432
michael@0 433 // A value passed to ProcessAttributeSignature is just an absolute number,
michael@0 434 // not an offset within the compilation unit as most of the other
michael@0 435 // DW_FORM_ref forms are. Check that the reader doesn't try to apply any
michael@0 436 // offset to the signature, by reading it from a compilation unit that does
michael@0 437 // not start at the beginning of the section.
michael@0 438 TEST_P(DwarfForms, ref_sig8_not_first) {
michael@0 439 info.Append(98, '*');
michael@0 440 StartSingleAttributeDIE(GetParam(), (DwarfTag) 0x253e7b2b,
michael@0 441 (DwarfAttribute) 0xd708d908,
michael@0 442 dwarf2reader::DW_FORM_ref_sig8);
michael@0 443 info.D64(0xf72fa0cb6ddcf9d6ULL);
michael@0 444 info.Finish();
michael@0 445
michael@0 446 ExpectBeginCompilationUnit(GetParam(), (DwarfTag) 0x253e7b2b, 98);
michael@0 447 EXPECT_CALL(handler, ProcessAttributeSignature(_, (DwarfAttribute) 0xd708d908,
michael@0 448 dwarf2reader::DW_FORM_ref_sig8,
michael@0 449 0xf72fa0cb6ddcf9d6ULL))
michael@0 450 .InSequence(s)
michael@0 451 .WillOnce(Return());
michael@0 452 ExpectEndCompilationUnit();
michael@0 453
michael@0 454 ParseCompilationUnit(GetParam(), 98);
michael@0 455 }
michael@0 456
michael@0 457 // Tests for the other attribute forms could go here.
michael@0 458
michael@0 459 INSTANTIATE_TEST_CASE_P(
michael@0 460 HeaderVariants, DwarfForms,
michael@0 461 ::testing::Values(DwarfHeaderParams(kLittleEndian, 4, 2, 4),
michael@0 462 DwarfHeaderParams(kLittleEndian, 4, 2, 8),
michael@0 463 DwarfHeaderParams(kLittleEndian, 4, 3, 4),
michael@0 464 DwarfHeaderParams(kLittleEndian, 4, 3, 8),
michael@0 465 DwarfHeaderParams(kLittleEndian, 4, 4, 4),
michael@0 466 DwarfHeaderParams(kLittleEndian, 4, 4, 8),
michael@0 467 DwarfHeaderParams(kLittleEndian, 8, 2, 4),
michael@0 468 DwarfHeaderParams(kLittleEndian, 8, 2, 8),
michael@0 469 DwarfHeaderParams(kLittleEndian, 8, 3, 4),
michael@0 470 DwarfHeaderParams(kLittleEndian, 8, 3, 8),
michael@0 471 DwarfHeaderParams(kLittleEndian, 8, 4, 4),
michael@0 472 DwarfHeaderParams(kLittleEndian, 8, 4, 8),
michael@0 473 DwarfHeaderParams(kBigEndian, 4, 2, 4),
michael@0 474 DwarfHeaderParams(kBigEndian, 4, 2, 8),
michael@0 475 DwarfHeaderParams(kBigEndian, 4, 3, 4),
michael@0 476 DwarfHeaderParams(kBigEndian, 4, 3, 8),
michael@0 477 DwarfHeaderParams(kBigEndian, 4, 4, 4),
michael@0 478 DwarfHeaderParams(kBigEndian, 4, 4, 8),
michael@0 479 DwarfHeaderParams(kBigEndian, 8, 2, 4),
michael@0 480 DwarfHeaderParams(kBigEndian, 8, 2, 8),
michael@0 481 DwarfHeaderParams(kBigEndian, 8, 3, 4),
michael@0 482 DwarfHeaderParams(kBigEndian, 8, 3, 8),
michael@0 483 DwarfHeaderParams(kBigEndian, 8, 4, 4),
michael@0 484 DwarfHeaderParams(kBigEndian, 8, 4, 8)));

mercurial