Home | History | Annotate | Download | only in dwarf
      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 (at) mozilla.com> <jimb (at) red-bean.com>
     31 
     32 // dwarf2reader_cfi_unittest.cc: Unit tests for dwarf2reader::CallFrameInfo
     33 
     34 #include <stdlib.h>
     35 
     36 #include <string>
     37 #include <vector>
     38 
     39 // The '.eh_frame' format, used by the Linux C++ ABI for exception
     40 // handling, is poorly specified. To help test our support for .eh_frame,
     41 // if you #define WRITE_ELF while compiling this file, and add the
     42 // 'include' directory from the binutils, gcc, or gdb source tree to the
     43 // #include path, then each test that calls the
     44 // PERHAPS_WRITE_DEBUG_FRAME_FILE or PERHAPS_WRITE_EH_FRAME_FILE will write
     45 // an ELF file containing a .debug_frame or .eh_frame section; you can then
     46 // use tools like readelf to examine the test data, and check the tools'
     47 // interpretation against the test's intentions. Each ELF file is named
     48 // "cfitest-TEST", where TEST identifies the particular test.
     49 #ifdef WRITE_ELF
     50 #include <errno.h>
     51 #include <stdio.h>
     52 #include <string.h>
     53 extern "C" {
     54 // To compile with WRITE_ELF, you should add the 'include' directory
     55 // of the binutils, gcc, or gdb source tree to your #include path;
     56 // that directory contains this header.
     57 #include "elf/common.h"
     58 }
     59 #endif
     60 
     61 #include "breakpad_googletest_includes.h"
     62 #include "common/dwarf/bytereader-inl.h"
     63 #include "common/dwarf/cfi_assembler.h"
     64 #include "common/dwarf/dwarf2reader.h"
     65 #include "common/using_std_string.h"
     66 #include "google_breakpad/common/breakpad_types.h"
     67 
     68 using google_breakpad::CFISection;
     69 using google_breakpad::test_assembler::Label;
     70 using google_breakpad::test_assembler::kBigEndian;
     71 using google_breakpad::test_assembler::kLittleEndian;
     72 using google_breakpad::test_assembler::Section;
     73 
     74 using dwarf2reader::DwarfPointerEncoding;
     75 using dwarf2reader::ENDIANNESS_BIG;
     76 using dwarf2reader::ENDIANNESS_LITTLE;
     77 using dwarf2reader::ByteReader;
     78 using dwarf2reader::CallFrameInfo;
     79 
     80 using std::vector;
     81 using testing::InSequence;
     82 using testing::Return;
     83 using testing::Sequence;
     84 using testing::Test;
     85 using testing::_;
     86 
     87 #ifdef WRITE_ELF
     88 void WriteELFFrameSection(const char *filename, const char *section_name,
     89                           const CFISection &section);
     90 #define PERHAPS_WRITE_DEBUG_FRAME_FILE(name, section)                   \
     91     WriteELFFrameSection("cfitest-" name, ".debug_frame", section);
     92 #define PERHAPS_WRITE_EH_FRAME_FILE(name, section)                      \
     93     WriteELFFrameSection("cfitest-" name, ".eh_frame", section);
     94 #else
     95 #define PERHAPS_WRITE_DEBUG_FRAME_FILE(name, section)
     96 #define PERHAPS_WRITE_EH_FRAME_FILE(name, section)
     97 #endif
     98 
     99 class MockCallFrameInfoHandler: public CallFrameInfo::Handler {
    100  public:
    101   MOCK_METHOD6(Entry, bool(size_t offset, uint64 address, uint64 length,
    102                            uint8 version, const string &augmentation,
    103                            unsigned return_address));
    104   MOCK_METHOD2(UndefinedRule, bool(uint64 address, int reg));
    105   MOCK_METHOD2(SameValueRule, bool(uint64 address, int reg));
    106   MOCK_METHOD4(OffsetRule, bool(uint64 address, int reg, int base_register,
    107                                 long offset));
    108   MOCK_METHOD4(ValOffsetRule, bool(uint64 address, int reg, int base_register,
    109                                    long offset));
    110   MOCK_METHOD3(RegisterRule, bool(uint64 address, int reg, int base_register));
    111   MOCK_METHOD3(ExpressionRule, bool(uint64 address, int reg,
    112                                     const string &expression));
    113   MOCK_METHOD3(ValExpressionRule, bool(uint64 address, int reg,
    114                                        const string &expression));
    115   MOCK_METHOD0(End, bool());
    116   MOCK_METHOD2(PersonalityRoutine, bool(uint64 address, bool indirect));
    117   MOCK_METHOD2(LanguageSpecificDataArea, bool(uint64 address, bool indirect));
    118   MOCK_METHOD0(SignalHandler, bool());
    119 };
    120 
    121 class MockCallFrameErrorReporter: public CallFrameInfo::Reporter {
    122  public:
    123   MockCallFrameErrorReporter() : Reporter("mock filename", "mock section") { }
    124   MOCK_METHOD2(Incomplete, void(uint64, CallFrameInfo::EntryKind));
    125   MOCK_METHOD1(EarlyEHTerminator, void(uint64));
    126   MOCK_METHOD2(CIEPointerOutOfRange, void(uint64, uint64));
    127   MOCK_METHOD2(BadCIEId, void(uint64, uint64));
    128   MOCK_METHOD2(UnrecognizedVersion, void(uint64, int version));
    129   MOCK_METHOD2(UnrecognizedAugmentation, void(uint64, const string &));
    130   MOCK_METHOD2(InvalidPointerEncoding, void(uint64, uint8));
    131   MOCK_METHOD2(UnusablePointerEncoding, void(uint64, uint8));
    132   MOCK_METHOD2(RestoreInCIE, void(uint64, uint64));
    133   MOCK_METHOD3(BadInstruction, void(uint64, CallFrameInfo::EntryKind, uint64));
    134   MOCK_METHOD3(NoCFARule, void(uint64, CallFrameInfo::EntryKind, uint64));
    135   MOCK_METHOD3(EmptyStateStack, void(uint64, CallFrameInfo::EntryKind, uint64));
    136 };
    137 
    138 struct CFIFixture {
    139 
    140   enum { kCFARegister = CallFrameInfo::Handler::kCFARegister };
    141 
    142   CFIFixture() {
    143     // Default expectations for the data handler.
    144     //
    145     // - Leave Entry and End without expectations, as it's probably a
    146     //   good idea to set those explicitly in each test.
    147     //
    148     // - Expect the *Rule functions to not be called,
    149     //   so that each test can simply list the calls they expect.
    150     //
    151     // I gather I could use StrictMock for this, but the manual seems
    152     // to suggest using that only as a last resort, and this isn't so
    153     // bad.
    154     EXPECT_CALL(handler, UndefinedRule(_, _)).Times(0);
    155     EXPECT_CALL(handler, SameValueRule(_, _)).Times(0);
    156     EXPECT_CALL(handler, OffsetRule(_, _, _, _)).Times(0);
    157     EXPECT_CALL(handler, ValOffsetRule(_, _, _, _)).Times(0);
    158     EXPECT_CALL(handler, RegisterRule(_, _, _)).Times(0);
    159     EXPECT_CALL(handler, ExpressionRule(_, _, _)).Times(0);
    160     EXPECT_CALL(handler, ValExpressionRule(_, _, _)).Times(0);
    161     EXPECT_CALL(handler, PersonalityRoutine(_, _)).Times(0);
    162     EXPECT_CALL(handler, LanguageSpecificDataArea(_, _)).Times(0);
    163     EXPECT_CALL(handler, SignalHandler()).Times(0);
    164 
    165     // Default expectations for the error/warning reporer.
    166     EXPECT_CALL(reporter, Incomplete(_, _)).Times(0);
    167     EXPECT_CALL(reporter, EarlyEHTerminator(_)).Times(0);
    168     EXPECT_CALL(reporter, CIEPointerOutOfRange(_, _)).Times(0);
    169     EXPECT_CALL(reporter, BadCIEId(_, _)).Times(0);
    170     EXPECT_CALL(reporter, UnrecognizedVersion(_, _)).Times(0);
    171     EXPECT_CALL(reporter, UnrecognizedAugmentation(_, _)).Times(0);
    172     EXPECT_CALL(reporter, InvalidPointerEncoding(_, _)).Times(0);
    173     EXPECT_CALL(reporter, UnusablePointerEncoding(_, _)).Times(0);
    174     EXPECT_CALL(reporter, RestoreInCIE(_, _)).Times(0);
    175     EXPECT_CALL(reporter, BadInstruction(_, _, _)).Times(0);
    176     EXPECT_CALL(reporter, NoCFARule(_, _, _)).Times(0);
    177     EXPECT_CALL(reporter, EmptyStateStack(_, _, _)).Times(0);
    178   }
    179 
    180   MockCallFrameInfoHandler handler;
    181   MockCallFrameErrorReporter reporter;
    182 };
    183 
    184 class CFI: public CFIFixture, public Test { };
    185 
    186 TEST_F(CFI, EmptyRegion) {
    187   EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
    188   EXPECT_CALL(handler, End()).Times(0);
    189   static const char data[1] = { 42 };
    190 
    191   ByteReader byte_reader(ENDIANNESS_BIG);
    192   CallFrameInfo parser(data, 0, &byte_reader, &handler, &reporter);
    193   EXPECT_TRUE(parser.Start());
    194 }
    195 
    196 TEST_F(CFI, IncompleteLength32) {
    197   CFISection section(kBigEndian, 8);
    198   section
    199       // Not even long enough for an initial length.
    200       .D16(0xa0f)
    201       // Padding to keep valgrind happy. We subtract these off when we
    202       // construct the parser.
    203       .D16(0);
    204 
    205   EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
    206   EXPECT_CALL(handler, End()).Times(0);
    207 
    208   EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown))
    209       .WillOnce(Return());
    210 
    211   string contents;
    212   ASSERT_TRUE(section.GetContents(&contents));
    213 
    214   ByteReader byte_reader(ENDIANNESS_BIG);
    215   byte_reader.SetAddressSize(8);
    216   CallFrameInfo parser(contents.data(), contents.size() - 2,
    217                        &byte_reader, &handler, &reporter);
    218   EXPECT_FALSE(parser.Start());
    219 }
    220 
    221 TEST_F(CFI, IncompleteLength64) {
    222   CFISection section(kLittleEndian, 4);
    223   section
    224       // An incomplete 64-bit DWARF initial length.
    225       .D32(0xffffffff).D32(0x71fbaec2)
    226       // Padding to keep valgrind happy. We subtract these off when we
    227       // construct the parser.
    228       .D32(0);
    229 
    230   EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
    231   EXPECT_CALL(handler, End()).Times(0);
    232 
    233   EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown))
    234       .WillOnce(Return());
    235 
    236   string contents;
    237   ASSERT_TRUE(section.GetContents(&contents));
    238 
    239   ByteReader byte_reader(ENDIANNESS_LITTLE);
    240   byte_reader.SetAddressSize(4);
    241   CallFrameInfo parser(contents.data(), contents.size() - 4,
    242                        &byte_reader, &handler, &reporter);
    243   EXPECT_FALSE(parser.Start());
    244 }
    245 
    246 TEST_F(CFI, IncompleteId32) {
    247   CFISection section(kBigEndian, 8);
    248   section
    249       .D32(3)                      // Initial length, not long enough for id
    250       .D8(0xd7).D8(0xe5).D8(0xf1)  // incomplete id
    251       .CIEHeader(8727, 3983, 8889, 3, "")
    252       .FinishEntry();
    253 
    254   EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
    255   EXPECT_CALL(handler, End()).Times(0);
    256 
    257   EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown))
    258       .WillOnce(Return());
    259 
    260   string contents;
    261   ASSERT_TRUE(section.GetContents(&contents));
    262 
    263   ByteReader byte_reader(ENDIANNESS_BIG);
    264   byte_reader.SetAddressSize(8);
    265   CallFrameInfo parser(contents.data(), contents.size(),
    266                        &byte_reader, &handler, &reporter);
    267   EXPECT_FALSE(parser.Start());
    268 }
    269 
    270 TEST_F(CFI, BadId32) {
    271   CFISection section(kBigEndian, 8);
    272   section
    273       .D32(0x100)                       // Initial length
    274       .D32(0xe802fade)                  // bogus ID
    275       .Append(0x100 - 4, 0x42);         // make the length true
    276   section
    277       .CIEHeader(1672, 9872, 8529, 3, "")
    278       .FinishEntry();
    279 
    280   EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
    281   EXPECT_CALL(handler, End()).Times(0);
    282 
    283   EXPECT_CALL(reporter, CIEPointerOutOfRange(_, 0xe802fade))
    284       .WillOnce(Return());
    285 
    286   string contents;
    287   ASSERT_TRUE(section.GetContents(&contents));
    288 
    289   ByteReader byte_reader(ENDIANNESS_BIG);
    290   byte_reader.SetAddressSize(8);
    291   CallFrameInfo parser(contents.data(), contents.size(),
    292                        &byte_reader, &handler, &reporter);
    293   EXPECT_FALSE(parser.Start());
    294 }
    295 
    296 // A lone CIE shouldn't cause any handler calls.
    297 TEST_F(CFI, SingleCIE) {
    298   CFISection section(kLittleEndian, 4);
    299   section.CIEHeader(0xffe799a8, 0x3398dcdd, 0x6e9683de, 3, "");
    300   section.Append(10, dwarf2reader::DW_CFA_nop);
    301   section.FinishEntry();
    302 
    303   PERHAPS_WRITE_DEBUG_FRAME_FILE("SingleCIE", section);
    304 
    305   EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
    306   EXPECT_CALL(handler, End()).Times(0);
    307 
    308   string contents;
    309   EXPECT_TRUE(section.GetContents(&contents));
    310   ByteReader byte_reader(ENDIANNESS_LITTLE);
    311   byte_reader.SetAddressSize(4);
    312   CallFrameInfo parser(contents.data(), contents.size(),
    313                        &byte_reader, &handler, &reporter);
    314   EXPECT_TRUE(parser.Start());
    315 }
    316 
    317 // One FDE, one CIE.
    318 TEST_F(CFI, OneFDE) {
    319   CFISection section(kBigEndian, 4);
    320   Label cie;
    321   section
    322       .Mark(&cie)
    323       .CIEHeader(0x4be22f75, 0x2492236e, 0x6b6efb87, 3, "")
    324       .FinishEntry()
    325       .FDEHeader(cie, 0x7714740d, 0x3d5a10cd)
    326       .FinishEntry();
    327 
    328   PERHAPS_WRITE_DEBUG_FRAME_FILE("OneFDE", section);
    329 
    330   {
    331     InSequence s;
    332     EXPECT_CALL(handler,
    333                 Entry(_, 0x7714740d, 0x3d5a10cd, 3, "", 0x6b6efb87))
    334         .WillOnce(Return(true));
    335     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    336   }
    337 
    338   string contents;
    339   EXPECT_TRUE(section.GetContents(&contents));
    340   ByteReader byte_reader(ENDIANNESS_BIG);
    341   byte_reader.SetAddressSize(4);
    342   CallFrameInfo parser(contents.data(), contents.size(),
    343                        &byte_reader, &handler, &reporter);
    344   EXPECT_TRUE(parser.Start());
    345 }
    346 
    347 // Two FDEs share a CIE.
    348 TEST_F(CFI, TwoFDEsOneCIE) {
    349   CFISection section(kBigEndian, 4);
    350   Label cie;
    351   section
    352       // First FDE. readelf complains about this one because it makes
    353       // a forward reference to its CIE.
    354       .FDEHeader(cie, 0xa42744df, 0xa3b42121)
    355       .FinishEntry()
    356       // CIE.
    357       .Mark(&cie)
    358       .CIEHeader(0x04f7dc7b, 0x3d00c05f, 0xbd43cb59, 3, "")
    359       .FinishEntry()
    360       // Second FDE.
    361       .FDEHeader(cie, 0x6057d391, 0x700f608d)
    362       .FinishEntry();
    363 
    364   PERHAPS_WRITE_DEBUG_FRAME_FILE("TwoFDEsOneCIE", section);
    365 
    366   {
    367     InSequence s;
    368     EXPECT_CALL(handler,
    369                 Entry(_, 0xa42744df, 0xa3b42121, 3, "", 0xbd43cb59))
    370         .WillOnce(Return(true));
    371     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    372   }
    373   {
    374     InSequence s;
    375     EXPECT_CALL(handler,
    376                 Entry(_, 0x6057d391, 0x700f608d, 3, "", 0xbd43cb59))
    377         .WillOnce(Return(true));
    378     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    379   }
    380 
    381   string contents;
    382   EXPECT_TRUE(section.GetContents(&contents));
    383   ByteReader byte_reader(ENDIANNESS_BIG);
    384   byte_reader.SetAddressSize(4);
    385   CallFrameInfo parser(contents.data(), contents.size(),
    386                        &byte_reader, &handler, &reporter);
    387   EXPECT_TRUE(parser.Start());
    388 }
    389 
    390 // Two FDEs, two CIEs.
    391 TEST_F(CFI, TwoFDEsTwoCIEs) {
    392   CFISection section(kLittleEndian, 8);
    393   Label cie1, cie2;
    394   section
    395       // First CIE.
    396       .Mark(&cie1)
    397       .CIEHeader(0x694d5d45, 0x4233221b, 0xbf45e65a, 3, "")
    398       .FinishEntry()
    399       // First FDE which cites second CIE. readelf complains about
    400       // this one because it makes a forward reference to its CIE.
    401       .FDEHeader(cie2, 0x778b27dfe5871f05ULL, 0x324ace3448070926ULL)
    402       .FinishEntry()
    403       // Second FDE, which cites first CIE.
    404       .FDEHeader(cie1, 0xf6054ca18b10bf5fULL, 0x45fdb970d8bca342ULL)
    405       .FinishEntry()
    406       // Second CIE.
    407       .Mark(&cie2)
    408       .CIEHeader(0xfba3fad7, 0x6287e1fd, 0x61d2c581, 2, "")
    409       .FinishEntry();
    410 
    411   PERHAPS_WRITE_DEBUG_FRAME_FILE("TwoFDEsTwoCIEs", section);
    412 
    413   {
    414     InSequence s;
    415     EXPECT_CALL(handler,
    416                 Entry(_, 0x778b27dfe5871f05ULL, 0x324ace3448070926ULL, 2,
    417                       "", 0x61d2c581))
    418         .WillOnce(Return(true));
    419     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    420   }
    421   {
    422     InSequence s;
    423     EXPECT_CALL(handler,
    424                 Entry(_, 0xf6054ca18b10bf5fULL, 0x45fdb970d8bca342ULL, 3,
    425                       "", 0xbf45e65a))
    426         .WillOnce(Return(true));
    427     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    428   }
    429 
    430   string contents;
    431   EXPECT_TRUE(section.GetContents(&contents));
    432   ByteReader byte_reader(ENDIANNESS_LITTLE);
    433   byte_reader.SetAddressSize(8);
    434   CallFrameInfo parser(contents.data(), contents.size(),
    435                        &byte_reader, &handler, &reporter);
    436   EXPECT_TRUE(parser.Start());
    437 }
    438 
    439 // An FDE whose CIE specifies a version we don't recognize.
    440 TEST_F(CFI, BadVersion) {
    441   CFISection section(kBigEndian, 4);
    442   Label cie1, cie2;
    443   section
    444       .Mark(&cie1)
    445       .CIEHeader(0xca878cf0, 0x7698ec04, 0x7b616f54, 0x52, "")
    446       .FinishEntry()
    447       // We should skip this entry, as its CIE specifies a version we
    448       // don't recognize.
    449       .FDEHeader(cie1, 0x08852292, 0x2204004a)
    450       .FinishEntry()
    451       // Despite the above, we should visit this entry.
    452       .Mark(&cie2)
    453       .CIEHeader(0x7c3ae7c9, 0xb9b9a512, 0x96cb3264, 3, "")
    454       .FinishEntry()
    455       .FDEHeader(cie2, 0x2094735a, 0x6e875501)
    456       .FinishEntry();
    457 
    458   PERHAPS_WRITE_DEBUG_FRAME_FILE("BadVersion", section);
    459 
    460   EXPECT_CALL(reporter, UnrecognizedVersion(_, 0x52))
    461     .WillOnce(Return());
    462 
    463   {
    464     InSequence s;
    465     // We should see no mention of the first FDE, but we should get
    466     // a call to Entry for the second.
    467     EXPECT_CALL(handler, Entry(_, 0x2094735a, 0x6e875501, 3, "",
    468                                0x96cb3264))
    469         .WillOnce(Return(true));
    470     EXPECT_CALL(handler, End())
    471         .WillOnce(Return(true));
    472   }
    473 
    474   string contents;
    475   EXPECT_TRUE(section.GetContents(&contents));
    476   ByteReader byte_reader(ENDIANNESS_BIG);
    477   byte_reader.SetAddressSize(4);
    478   CallFrameInfo parser(contents.data(), contents.size(),
    479                        &byte_reader, &handler, &reporter);
    480   EXPECT_FALSE(parser.Start());
    481 }
    482 
    483 // An FDE whose CIE specifies an augmentation we don't recognize.
    484 TEST_F(CFI, BadAugmentation) {
    485   CFISection section(kBigEndian, 4);
    486   Label cie1, cie2;
    487   section
    488       .Mark(&cie1)
    489       .CIEHeader(0x4be22f75, 0x2492236e, 0x6b6efb87, 3, "spaniels!")
    490       .FinishEntry()
    491       // We should skip this entry, as its CIE specifies an
    492       // augmentation we don't recognize.
    493       .FDEHeader(cie1, 0x7714740d, 0x3d5a10cd)
    494       .FinishEntry()
    495       // Despite the above, we should visit this entry.
    496       .Mark(&cie2)
    497       .CIEHeader(0xf8bc4399, 0x8cf09931, 0xf2f519b2, 3, "")
    498       .FinishEntry()
    499       .FDEHeader(cie2, 0x7bf0fda0, 0xcbcd28d8)
    500       .FinishEntry();
    501 
    502   PERHAPS_WRITE_DEBUG_FRAME_FILE("BadAugmentation", section);
    503 
    504   EXPECT_CALL(reporter, UnrecognizedAugmentation(_, "spaniels!"))
    505     .WillOnce(Return());
    506 
    507   {
    508     InSequence s;
    509     // We should see no mention of the first FDE, but we should get
    510     // a call to Entry for the second.
    511     EXPECT_CALL(handler, Entry(_, 0x7bf0fda0, 0xcbcd28d8, 3, "",
    512                                0xf2f519b2))
    513         .WillOnce(Return(true));
    514     EXPECT_CALL(handler, End())
    515         .WillOnce(Return(true));
    516   }
    517 
    518   string contents;
    519   EXPECT_TRUE(section.GetContents(&contents));
    520   ByteReader byte_reader(ENDIANNESS_BIG);
    521   byte_reader.SetAddressSize(4);
    522   CallFrameInfo parser(contents.data(), contents.size(),
    523                        &byte_reader, &handler, &reporter);
    524   EXPECT_FALSE(parser.Start());
    525 }
    526 
    527 // The return address column field is a byte in CFI version 1
    528 // (DWARF2), but a ULEB128 value in version 3 (DWARF3).
    529 TEST_F(CFI, CIEVersion1ReturnColumn) {
    530   CFISection section(kBigEndian, 4);
    531   Label cie;
    532   section
    533       // CIE, using the version 1 format: return column is a ubyte.
    534       .Mark(&cie)
    535       // Use a value for the return column that is parsed differently
    536       // as a ubyte and as a ULEB128.
    537       .CIEHeader(0xbcdea24f, 0x5be28286, 0x9f, 1, "")
    538       .FinishEntry()
    539       // FDE, citing that CIE.
    540       .FDEHeader(cie, 0xb8d347b5, 0x825e55dc)
    541       .FinishEntry();
    542 
    543   PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion1ReturnColumn", section);
    544 
    545   {
    546     InSequence s;
    547     EXPECT_CALL(handler, Entry(_, 0xb8d347b5, 0x825e55dc, 1, "", 0x9f))
    548         .WillOnce(Return(true));
    549     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    550   }
    551 
    552   string contents;
    553   EXPECT_TRUE(section.GetContents(&contents));
    554   ByteReader byte_reader(ENDIANNESS_BIG);
    555   byte_reader.SetAddressSize(4);
    556   CallFrameInfo parser(contents.data(), contents.size(),
    557                        &byte_reader, &handler, &reporter);
    558   EXPECT_TRUE(parser.Start());
    559 }
    560 
    561 // The return address column field is a byte in CFI version 1
    562 // (DWARF2), but a ULEB128 value in version 3 (DWARF3).
    563 TEST_F(CFI, CIEVersion3ReturnColumn) {
    564   CFISection section(kBigEndian, 4);
    565   Label cie;
    566   section
    567       // CIE, using the version 3 format: return column is a ULEB128.
    568       .Mark(&cie)
    569       // Use a value for the return column that is parsed differently
    570       // as a ubyte and as a ULEB128.
    571       .CIEHeader(0x0ab4758d, 0xc010fdf7, 0x89, 3, "")
    572       .FinishEntry()
    573       // FDE, citing that CIE.
    574       .FDEHeader(cie, 0x86763f2b, 0x2a66dc23)
    575       .FinishEntry();
    576 
    577   PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion3ReturnColumn", section);
    578 
    579   {
    580     InSequence s;
    581     EXPECT_CALL(handler, Entry(_, 0x86763f2b, 0x2a66dc23, 3, "", 0x89))
    582         .WillOnce(Return(true));
    583     EXPECT_CALL(handler, End()).WillOnce(Return(true));
    584   }
    585 
    586   string contents;
    587   EXPECT_TRUE(section.GetContents(&contents));
    588   ByteReader byte_reader(ENDIANNESS_BIG);
    589   byte_reader.SetAddressSize(4);
    590   CallFrameInfo parser(contents.data(), contents.size(),
    591                        &byte_reader, &handler, &reporter);
    592   EXPECT_TRUE(parser.Start());
    593 }
    594 
    595 struct CFIInsnFixture: public CFIFixture {
    596   CFIInsnFixture() : CFIFixture() {
    597     data_factor = 0xb6f;
    598     return_register = 0x9be1ed9f;
    599     version = 3;
    600     cfa_base_register = 0x383a3aa;
    601     cfa_offset = 0xf748;
    602   }
    603 
    604   // Prepare SECTION to receive FDE instructions.
    605   //
    606   // - Append a stock CIE header that establishes the fixture's
    607   //   code_factor, data_factor, return_register, version, and
    608   //   augmentation values.
    609   // - Have the CIE set up a CFA rule using cfa_base_register and
    610   //   cfa_offset.
    611   // - Append a stock FDE header, referring to the above CIE, for the
    612   //   fde_size bytes at fde_start. Choose fde_start and fde_size
    613   //   appropriately for the section's address size.
    614   // - Set appropriate expectations on handler in sequence s for the
    615   //   frame description entry and the CIE's CFA rule.
    616   //
    617   // On return, SECTION is ready to have FDE instructions appended to
    618   // it, and its FinishEntry member called.
    619   void StockCIEAndFDE(CFISection *section) {
    620     // Choose appropriate constants for our address size.
    621     if (section->AddressSize() == 4) {
    622       fde_start = 0xc628ecfbU;
    623       fde_size = 0x5dee04a2;
    624       code_factor = 0x60b;
    625     } else {
    626       assert(section->AddressSize() == 8);
    627       fde_start = 0x0005c57ce7806bd3ULL;
    628       fde_size = 0x2699521b5e333100ULL;
    629       code_factor = 0x01008e32855274a8ULL;
    630     }
    631 
    632     // Create the CIE.
    633     (*section)
    634         .Mark(&cie_label)
    635         .CIEHeader(code_factor, data_factor, return_register, version,
    636                    "")
    637         .D8(dwarf2reader::DW_CFA_def_cfa)
    638         .ULEB128(cfa_base_register)
    639         .ULEB128(cfa_offset)
    640         .FinishEntry();
    641 
    642     // Create the FDE.
    643     section->FDEHeader(cie_label, fde_start, fde_size);
    644 
    645     // Expect an Entry call for the FDE and a ValOffsetRule call for the
    646     // CIE's CFA rule.
    647     EXPECT_CALL(handler, Entry(_, fde_start, fde_size, version, "",
    648                                return_register))
    649         .InSequence(s)
    650         .WillOnce(Return(true));
    651     EXPECT_CALL(handler, ValOffsetRule(fde_start, kCFARegister,
    652                                        cfa_base_register, cfa_offset))
    653       .InSequence(s)
    654       .WillOnce(Return(true));
    655   }
    656 
    657   // Run the contents of SECTION through a CallFrameInfo parser,
    658   // expecting parser.Start to return SUCCEEDS
    659   void ParseSection(CFISection *section, bool succeeds = true) {
    660     string contents;
    661     EXPECT_TRUE(section->GetContents(&contents));
    662     dwarf2reader::Endianness endianness;
    663     if (section->endianness() == kBigEndian)
    664       endianness = ENDIANNESS_BIG;
    665     else {
    666       assert(section->endianness() == kLittleEndian);
    667       endianness = ENDIANNESS_LITTLE;
    668     }
    669     ByteReader byte_reader(endianness);
    670     byte_reader.SetAddressSize(section->AddressSize());
    671     CallFrameInfo parser(contents.data(), contents.size(),
    672                          &byte_reader, &handler, &reporter);
    673     if (succeeds)
    674       EXPECT_TRUE(parser.Start());
    675     else
    676       EXPECT_FALSE(parser.Start());
    677   }
    678 
    679   Label cie_label;
    680   Sequence s;
    681   uint64 code_factor;
    682   int data_factor;
    683   unsigned return_register;
    684   unsigned version;
    685   unsigned cfa_base_register;
    686   int cfa_offset;
    687   uint64 fde_start, fde_size;
    688 };
    689 
    690 class CFIInsn: public CFIInsnFixture, public Test { };
    691 
    692 TEST_F(CFIInsn, DW_CFA_set_loc) {
    693   CFISection section(kBigEndian, 4);
    694   StockCIEAndFDE(&section);
    695   section
    696       .D8(dwarf2reader::DW_CFA_set_loc).D32(0xb1ee3e7a)
    697       // Use DW_CFA_def_cfa to force a handler call that we can use to
    698       // check the effect of the DW_CFA_set_loc.
    699       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x4defb431).ULEB128(0x6d17b0ee)
    700       .FinishEntry();
    701 
    702   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_set_loc", section);
    703 
    704   EXPECT_CALL(handler,
    705               ValOffsetRule(0xb1ee3e7a, kCFARegister, 0x4defb431, 0x6d17b0ee))
    706       .InSequence(s)
    707       .WillOnce(Return(true));
    708   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    709 
    710   ParseSection(&section);
    711 }
    712 
    713 TEST_F(CFIInsn, DW_CFA_advance_loc) {
    714   CFISection section(kBigEndian, 8);
    715   StockCIEAndFDE(&section);
    716   section
    717       .D8(dwarf2reader::DW_CFA_advance_loc | 0x2a)
    718       // Use DW_CFA_def_cfa to force a handler call that we can use to
    719       // check the effect of the DW_CFA_advance_loc.
    720       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x5bbb3715).ULEB128(0x0186c7bf)
    721       .FinishEntry();
    722 
    723   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc", section);
    724 
    725   EXPECT_CALL(handler,
    726               ValOffsetRule(fde_start + 0x2a * code_factor,
    727                             kCFARegister, 0x5bbb3715, 0x0186c7bf))
    728         .InSequence(s)
    729         .WillOnce(Return(true));
    730   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    731 
    732   ParseSection(&section);
    733 }
    734 
    735 TEST_F(CFIInsn, DW_CFA_advance_loc1) {
    736   CFISection section(kLittleEndian, 8);
    737   StockCIEAndFDE(&section);
    738   section
    739       .D8(dwarf2reader::DW_CFA_advance_loc1).D8(0xd8)
    740       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x69d5696a).ULEB128(0x1eb7fc93)
    741       .FinishEntry();
    742 
    743   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc1", section);
    744 
    745   EXPECT_CALL(handler,
    746               ValOffsetRule((fde_start + 0xd8 * code_factor),
    747                             kCFARegister, 0x69d5696a, 0x1eb7fc93))
    748       .InSequence(s)
    749       .WillOnce(Return(true));
    750   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    751 
    752   ParseSection(&section);
    753 }
    754 
    755 TEST_F(CFIInsn, DW_CFA_advance_loc2) {
    756   CFISection section(kLittleEndian, 4);
    757   StockCIEAndFDE(&section);
    758   section
    759       .D8(dwarf2reader::DW_CFA_advance_loc2).D16(0x3adb)
    760       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x3a368bed).ULEB128(0x3194ee37)
    761       .FinishEntry();
    762 
    763   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc2", section);
    764 
    765   EXPECT_CALL(handler,
    766               ValOffsetRule((fde_start + 0x3adb * code_factor),
    767                             kCFARegister, 0x3a368bed, 0x3194ee37))
    768       .InSequence(s)
    769       .WillOnce(Return(true));
    770   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    771 
    772   ParseSection(&section);
    773 }
    774 
    775 TEST_F(CFIInsn, DW_CFA_advance_loc4) {
    776   CFISection section(kBigEndian, 8);
    777   StockCIEAndFDE(&section);
    778   section
    779       .D8(dwarf2reader::DW_CFA_advance_loc4).D32(0x15813c88)
    780       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x135270c5).ULEB128(0x24bad7cb)
    781       .FinishEntry();
    782 
    783   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc4", section);
    784 
    785   EXPECT_CALL(handler,
    786               ValOffsetRule((fde_start + 0x15813c88ULL * code_factor),
    787                             kCFARegister, 0x135270c5, 0x24bad7cb))
    788       .InSequence(s)
    789       .WillOnce(Return(true));
    790   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    791 
    792   ParseSection(&section);
    793 }
    794 
    795 TEST_F(CFIInsn, DW_CFA_MIPS_advance_loc8) {
    796   code_factor = 0x2d;
    797   CFISection section(kBigEndian, 8);
    798   StockCIEAndFDE(&section);
    799   section
    800       .D8(dwarf2reader::DW_CFA_MIPS_advance_loc8).D64(0x3c4f3945b92c14ULL)
    801       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0xe17ed602).ULEB128(0x3d162e7f)
    802       .FinishEntry();
    803 
    804   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc8", section);
    805 
    806   EXPECT_CALL(handler,
    807               ValOffsetRule((fde_start + 0x3c4f3945b92c14ULL * code_factor),
    808                             kCFARegister, 0xe17ed602, 0x3d162e7f))
    809       .InSequence(s)
    810       .WillOnce(Return(true));
    811   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    812 
    813   ParseSection(&section);
    814 }
    815 
    816 TEST_F(CFIInsn, DW_CFA_def_cfa) {
    817   CFISection section(kLittleEndian, 4);
    818   StockCIEAndFDE(&section);
    819   section
    820       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x4e363a85).ULEB128(0x815f9aa7)
    821       .FinishEntry();
    822 
    823   PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_def_cfa", section);
    824 
    825   EXPECT_CALL(handler,
    826               ValOffsetRule(fde_start, kCFARegister, 0x4e363a85, 0x815f9aa7))
    827       .InSequence(s).WillOnce(Return(true));
    828   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    829 
    830   ParseSection(&section);
    831 }
    832 
    833 TEST_F(CFIInsn, DW_CFA_def_cfa_sf) {
    834   CFISection section(kBigEndian, 4);
    835   StockCIEAndFDE(&section);
    836   section
    837       .D8(dwarf2reader::DW_CFA_def_cfa_sf).ULEB128(0x8ccb32b7).LEB128(0x9ea)
    838       .D8(dwarf2reader::DW_CFA_def_cfa_sf).ULEB128(0x9b40f5da).LEB128(-0x40a2)
    839       .FinishEntry();
    840 
    841   EXPECT_CALL(handler,
    842               ValOffsetRule(fde_start, kCFARegister, 0x8ccb32b7,
    843                             0x9ea * data_factor))
    844       .InSequence(s).WillOnce(Return(true));
    845   EXPECT_CALL(handler,
    846               ValOffsetRule(fde_start, kCFARegister, 0x9b40f5da,
    847                             -0x40a2 * data_factor))
    848       .InSequence(s).WillOnce(Return(true));
    849   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    850 
    851   ParseSection(&section);
    852 }
    853 
    854 TEST_F(CFIInsn, DW_CFA_def_cfa_register) {
    855   CFISection section(kLittleEndian, 8);
    856   StockCIEAndFDE(&section);
    857   section
    858       .D8(dwarf2reader::DW_CFA_def_cfa_register).ULEB128(0x3e7e9363)
    859       .FinishEntry();
    860 
    861   EXPECT_CALL(handler,
    862               ValOffsetRule(fde_start, kCFARegister, 0x3e7e9363, cfa_offset))
    863       .InSequence(s).WillOnce(Return(true));
    864   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    865 
    866   ParseSection(&section);
    867 }
    868 
    869 // DW_CFA_def_cfa_register should have no effect when applied to a
    870 // non-base/offset rule.
    871 TEST_F(CFIInsn, DW_CFA_def_cfa_registerBadRule) {
    872   CFISection section(kBigEndian, 4);
    873   StockCIEAndFDE(&section);
    874   section
    875       .D8(dwarf2reader::DW_CFA_def_cfa_expression).Block("needle in a haystack")
    876       .D8(dwarf2reader::DW_CFA_def_cfa_register).ULEB128(0xf1b49e49)
    877       .FinishEntry();
    878 
    879   EXPECT_CALL(handler,
    880               ValExpressionRule(fde_start, kCFARegister,
    881                                 "needle in a haystack"))
    882       .WillRepeatedly(Return(true));
    883   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    884 
    885   ParseSection(&section);
    886 }
    887 
    888 TEST_F(CFIInsn, DW_CFA_def_cfa_offset) {
    889   CFISection section(kBigEndian, 4);
    890   StockCIEAndFDE(&section);
    891   section
    892       .D8(dwarf2reader::DW_CFA_def_cfa_offset).ULEB128(0x1e8e3b9b)
    893       .FinishEntry();
    894 
    895   EXPECT_CALL(handler,
    896               ValOffsetRule(fde_start, kCFARegister, cfa_base_register,
    897                             0x1e8e3b9b))
    898       .InSequence(s).WillOnce(Return(true));
    899   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    900 
    901   ParseSection(&section);
    902 }
    903 
    904 TEST_F(CFIInsn, DW_CFA_def_cfa_offset_sf) {
    905   CFISection section(kLittleEndian, 4);
    906   StockCIEAndFDE(&section);
    907   section
    908       .D8(dwarf2reader::DW_CFA_def_cfa_offset_sf).LEB128(0x970)
    909       .D8(dwarf2reader::DW_CFA_def_cfa_offset_sf).LEB128(-0x2cd)
    910       .FinishEntry();
    911 
    912   EXPECT_CALL(handler,
    913               ValOffsetRule(fde_start, kCFARegister, cfa_base_register,
    914                             0x970 * data_factor))
    915       .InSequence(s).WillOnce(Return(true));
    916   EXPECT_CALL(handler,
    917               ValOffsetRule(fde_start, kCFARegister, cfa_base_register,
    918                             -0x2cd * data_factor))
    919       .InSequence(s).WillOnce(Return(true));
    920   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    921 
    922   ParseSection(&section);
    923 }
    924 
    925 // DW_CFA_def_cfa_offset should have no effect when applied to a
    926 // non-base/offset rule.
    927 TEST_F(CFIInsn, DW_CFA_def_cfa_offsetBadRule) {
    928   CFISection section(kBigEndian, 4);
    929   StockCIEAndFDE(&section);
    930   section
    931       .D8(dwarf2reader::DW_CFA_def_cfa_expression).Block("six ways to Sunday")
    932       .D8(dwarf2reader::DW_CFA_def_cfa_offset).ULEB128(0x1e8e3b9b)
    933       .FinishEntry();
    934 
    935   EXPECT_CALL(handler,
    936               ValExpressionRule(fde_start, kCFARegister, "six ways to Sunday"))
    937       .WillRepeatedly(Return(true));
    938   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    939 
    940   ParseSection(&section);
    941 }
    942 
    943 TEST_F(CFIInsn, DW_CFA_def_cfa_expression) {
    944   CFISection section(kLittleEndian, 8);
    945   StockCIEAndFDE(&section);
    946   section
    947       .D8(dwarf2reader::DW_CFA_def_cfa_expression).Block("eating crow")
    948       .FinishEntry();
    949 
    950   EXPECT_CALL(handler, ValExpressionRule(fde_start, kCFARegister,
    951                                          "eating crow"))
    952       .InSequence(s).WillOnce(Return(true));
    953   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    954 
    955   ParseSection(&section);
    956 }
    957 
    958 TEST_F(CFIInsn, DW_CFA_undefined) {
    959   CFISection section(kLittleEndian, 4);
    960   StockCIEAndFDE(&section);
    961   section
    962       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x300ce45d)
    963       .FinishEntry();
    964 
    965   EXPECT_CALL(handler, UndefinedRule(fde_start, 0x300ce45d))
    966       .InSequence(s).WillOnce(Return(true));
    967   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    968 
    969   ParseSection(&section);
    970 }
    971 
    972 TEST_F(CFIInsn, DW_CFA_same_value) {
    973   CFISection section(kLittleEndian, 4);
    974   StockCIEAndFDE(&section);
    975   section
    976       .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0x3865a760)
    977       .FinishEntry();
    978 
    979   EXPECT_CALL(handler, SameValueRule(fde_start, 0x3865a760))
    980       .InSequence(s).WillOnce(Return(true));
    981   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    982 
    983   ParseSection(&section);
    984 }
    985 
    986 TEST_F(CFIInsn, DW_CFA_offset) {
    987   CFISection section(kBigEndian, 4);
    988   StockCIEAndFDE(&section);
    989   section
    990       .D8(dwarf2reader::DW_CFA_offset | 0x2c).ULEB128(0x9f6)
    991       .FinishEntry();
    992 
    993   EXPECT_CALL(handler,
    994               OffsetRule(fde_start, 0x2c, kCFARegister, 0x9f6 * data_factor))
    995       .InSequence(s).WillOnce(Return(true));
    996   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
    997 
    998   ParseSection(&section);
    999 }
   1000 
   1001 TEST_F(CFIInsn, DW_CFA_offset_extended) {
   1002   CFISection section(kBigEndian, 4);
   1003   StockCIEAndFDE(&section);
   1004   section
   1005       .D8(dwarf2reader::DW_CFA_offset_extended).ULEB128(0x402b).ULEB128(0xb48)
   1006       .FinishEntry();
   1007 
   1008   EXPECT_CALL(handler,
   1009               OffsetRule(fde_start, 0x402b, kCFARegister, 0xb48 * data_factor))
   1010       .InSequence(s).WillOnce(Return(true));
   1011   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1012 
   1013   ParseSection(&section);
   1014 }
   1015 
   1016 TEST_F(CFIInsn, DW_CFA_offset_extended_sf) {
   1017   CFISection section(kBigEndian, 8);
   1018   StockCIEAndFDE(&section);
   1019   section
   1020       .D8(dwarf2reader::DW_CFA_offset_extended_sf)
   1021           .ULEB128(0x997c23ee).LEB128(0x2d00)
   1022       .D8(dwarf2reader::DW_CFA_offset_extended_sf)
   1023           .ULEB128(0x9519eb82).LEB128(-0xa77)
   1024       .FinishEntry();
   1025 
   1026   EXPECT_CALL(handler,
   1027               OffsetRule(fde_start, 0x997c23ee,
   1028                          kCFARegister, 0x2d00 * data_factor))
   1029       .InSequence(s).WillOnce(Return(true));
   1030   EXPECT_CALL(handler,
   1031               OffsetRule(fde_start, 0x9519eb82,
   1032                          kCFARegister, -0xa77 * data_factor))
   1033       .InSequence(s).WillOnce(Return(true));
   1034   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1035 
   1036   ParseSection(&section);
   1037 }
   1038 
   1039 TEST_F(CFIInsn, DW_CFA_val_offset) {
   1040   CFISection section(kBigEndian, 4);
   1041   StockCIEAndFDE(&section);
   1042   section
   1043       .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x623562fe).ULEB128(0x673)
   1044       .FinishEntry();
   1045 
   1046   EXPECT_CALL(handler,
   1047               ValOffsetRule(fde_start, 0x623562fe,
   1048                             kCFARegister, 0x673 * data_factor))
   1049       .InSequence(s).WillOnce(Return(true));
   1050   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1051 
   1052   ParseSection(&section);
   1053 }
   1054 
   1055 TEST_F(CFIInsn, DW_CFA_val_offset_sf) {
   1056   CFISection section(kBigEndian, 4);
   1057   StockCIEAndFDE(&section);
   1058   section
   1059       .D8(dwarf2reader::DW_CFA_val_offset_sf).ULEB128(0x6f4f).LEB128(0xaab)
   1060       .D8(dwarf2reader::DW_CFA_val_offset_sf).ULEB128(0x2483).LEB128(-0x8a2)
   1061       .FinishEntry();
   1062 
   1063   EXPECT_CALL(handler,
   1064               ValOffsetRule(fde_start, 0x6f4f,
   1065                             kCFARegister, 0xaab * data_factor))
   1066       .InSequence(s).WillOnce(Return(true));
   1067   EXPECT_CALL(handler,
   1068               ValOffsetRule(fde_start, 0x2483,
   1069                             kCFARegister, -0x8a2 * data_factor))
   1070       .InSequence(s).WillOnce(Return(true));
   1071   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1072 
   1073   ParseSection(&section);
   1074 }
   1075 
   1076 TEST_F(CFIInsn, DW_CFA_register) {
   1077   CFISection section(kLittleEndian, 8);
   1078   StockCIEAndFDE(&section);
   1079   section
   1080       .D8(dwarf2reader::DW_CFA_register).ULEB128(0x278d18f9).ULEB128(0x1a684414)
   1081       .FinishEntry();
   1082 
   1083   EXPECT_CALL(handler, RegisterRule(fde_start, 0x278d18f9, 0x1a684414))
   1084       .InSequence(s).WillOnce(Return(true));
   1085   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1086 
   1087   ParseSection(&section);
   1088 }
   1089 
   1090 TEST_F(CFIInsn, DW_CFA_expression) {
   1091   CFISection section(kBigEndian, 8);
   1092   StockCIEAndFDE(&section);
   1093   section
   1094       .D8(dwarf2reader::DW_CFA_expression).ULEB128(0xa1619fb2)
   1095       .Block("plus a change, plus c'est la mme chose")
   1096       .FinishEntry();
   1097 
   1098   EXPECT_CALL(handler,
   1099               ExpressionRule(fde_start, 0xa1619fb2,
   1100                              "plus a change, plus c'est la mme chose"))
   1101       .InSequence(s).WillOnce(Return(true));
   1102   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1103 
   1104   ParseSection(&section);
   1105 }
   1106 
   1107 TEST_F(CFIInsn, DW_CFA_val_expression) {
   1108   CFISection section(kBigEndian, 4);
   1109   StockCIEAndFDE(&section);
   1110   section
   1111       .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0xc5e4a9e3)
   1112       .Block("he who has the gold makes the rules")
   1113       .FinishEntry();
   1114 
   1115   EXPECT_CALL(handler,
   1116               ValExpressionRule(fde_start, 0xc5e4a9e3,
   1117                                 "he who has the gold makes the rules"))
   1118       .InSequence(s).WillOnce(Return(true));
   1119   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1120 
   1121   ParseSection(&section);
   1122 }
   1123 
   1124 TEST_F(CFIInsn, DW_CFA_restore) {
   1125   CFISection section(kLittleEndian, 8);
   1126   code_factor = 0x01bd188a9b1fa083ULL;
   1127   data_factor = -0x1ac8;
   1128   return_register = 0x8c35b049;
   1129   version = 2;
   1130   fde_start = 0x2d70fe998298bbb1ULL;
   1131   fde_size = 0x46ccc2e63cf0b108ULL;
   1132   Label cie;
   1133   section
   1134       .Mark(&cie)
   1135       .CIEHeader(code_factor, data_factor, return_register, version,
   1136                  "")
   1137       // Provide a CFA rule, because register rules require them.
   1138       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x6ca1d50e).ULEB128(0x372e38e8)
   1139       // Provide an offset(N) rule for register 0x3c.
   1140       .D8(dwarf2reader::DW_CFA_offset | 0x3c).ULEB128(0xb348)
   1141       .FinishEntry()
   1142       // In the FDE...
   1143       .FDEHeader(cie, fde_start, fde_size)
   1144       // At a second address, provide a new offset(N) rule for register 0x3c.
   1145       .D8(dwarf2reader::DW_CFA_advance_loc | 0x13)
   1146       .D8(dwarf2reader::DW_CFA_offset | 0x3c).ULEB128(0x9a50)
   1147       // At a third address, restore the original rule for register 0x3c.
   1148       .D8(dwarf2reader::DW_CFA_advance_loc | 0x01)
   1149       .D8(dwarf2reader::DW_CFA_restore | 0x3c)
   1150       .FinishEntry();
   1151 
   1152   {
   1153     InSequence s;
   1154     EXPECT_CALL(handler,
   1155                 Entry(_, fde_start, fde_size, version, "", return_register))
   1156         .WillOnce(Return(true));
   1157     // CIE's CFA rule.
   1158     EXPECT_CALL(handler,
   1159                 ValOffsetRule(fde_start, kCFARegister, 0x6ca1d50e, 0x372e38e8))
   1160         .WillOnce(Return(true));
   1161     // CIE's rule for register 0x3c.
   1162     EXPECT_CALL(handler,
   1163                 OffsetRule(fde_start, 0x3c, kCFARegister, 0xb348 * data_factor))
   1164         .WillOnce(Return(true));
   1165     // FDE's rule for register 0x3c.
   1166     EXPECT_CALL(handler,
   1167                 OffsetRule(fde_start + 0x13 * code_factor, 0x3c,
   1168                            kCFARegister, 0x9a50 * data_factor))
   1169         .WillOnce(Return(true));
   1170     // Restore CIE's rule for register 0x3c.
   1171     EXPECT_CALL(handler,
   1172                 OffsetRule(fde_start + (0x13 + 0x01) * code_factor, 0x3c,
   1173                            kCFARegister, 0xb348 * data_factor))
   1174         .WillOnce(Return(true));
   1175     EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1176   }
   1177 
   1178   ParseSection(&section);
   1179 }
   1180 
   1181 TEST_F(CFIInsn, DW_CFA_restoreNoRule) {
   1182   CFISection section(kBigEndian, 4);
   1183   code_factor = 0x005f78143c1c3b82ULL;
   1184   data_factor = 0x25d0;
   1185   return_register = 0xe8;
   1186   version = 1;
   1187   fde_start = 0x4062e30f;
   1188   fde_size = 0x5302a389;
   1189   Label cie;
   1190   section
   1191       .Mark(&cie)
   1192       .CIEHeader(code_factor, data_factor, return_register, version, "")
   1193       // Provide a CFA rule, because register rules require them.
   1194       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x470aa334).ULEB128(0x099ef127)
   1195       .FinishEntry()
   1196       // In the FDE...
   1197       .FDEHeader(cie, fde_start, fde_size)
   1198       // At a second address, provide an offset(N) rule for register 0x2c.
   1199       .D8(dwarf2reader::DW_CFA_advance_loc | 0x7)
   1200       .D8(dwarf2reader::DW_CFA_offset | 0x2c).ULEB128(0x1f47)
   1201       // At a third address, restore the (missing) CIE rule for register 0x2c.
   1202       .D8(dwarf2reader::DW_CFA_advance_loc | 0xb)
   1203       .D8(dwarf2reader::DW_CFA_restore | 0x2c)
   1204       .FinishEntry();
   1205 
   1206   {
   1207     InSequence s;
   1208     EXPECT_CALL(handler,
   1209                 Entry(_, fde_start, fde_size, version, "", return_register))
   1210         .WillOnce(Return(true));
   1211     // CIE's CFA rule.
   1212     EXPECT_CALL(handler,
   1213                 ValOffsetRule(fde_start, kCFARegister, 0x470aa334, 0x099ef127))
   1214         .WillOnce(Return(true));
   1215     // FDE's rule for register 0x2c.
   1216     EXPECT_CALL(handler,
   1217                 OffsetRule(fde_start + 0x7 * code_factor, 0x2c,
   1218                            kCFARegister, 0x1f47 * data_factor))
   1219         .WillOnce(Return(true));
   1220     // Restore CIE's (missing) rule for register 0x2c.
   1221     EXPECT_CALL(handler,
   1222                 SameValueRule(fde_start + (0x7 + 0xb) * code_factor, 0x2c))
   1223         .WillOnce(Return(true));
   1224     EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1225   }
   1226 
   1227   ParseSection(&section);
   1228 }
   1229 
   1230 TEST_F(CFIInsn, DW_CFA_restore_extended) {
   1231   CFISection section(kBigEndian, 4);
   1232   code_factor = 0x126e;
   1233   data_factor = -0xd8b;
   1234   return_register = 0x77711787;
   1235   version = 3;
   1236   fde_start = 0x01f55a45;
   1237   fde_size = 0x452adb80;
   1238   Label cie;
   1239   section
   1240       .Mark(&cie)
   1241       .CIEHeader(code_factor, data_factor, return_register, version,
   1242                  "", true /* dwarf64 */ )
   1243       // Provide a CFA rule, because register rules require them.
   1244       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x56fa0edd).ULEB128(0x097f78a5)
   1245       // Provide an offset(N) rule for register 0x0f9b8a1c.
   1246       .D8(dwarf2reader::DW_CFA_offset_extended)
   1247           .ULEB128(0x0f9b8a1c).ULEB128(0xc979)
   1248       .FinishEntry()
   1249       // In the FDE...
   1250       .FDEHeader(cie, fde_start, fde_size)
   1251       // At a second address, provide a new offset(N) rule for reg 0x0f9b8a1c.
   1252       .D8(dwarf2reader::DW_CFA_advance_loc | 0x3)
   1253       .D8(dwarf2reader::DW_CFA_offset_extended)
   1254           .ULEB128(0x0f9b8a1c).ULEB128(0x3b7b)
   1255       // At a third address, restore the original rule for register 0x0f9b8a1c.
   1256       .D8(dwarf2reader::DW_CFA_advance_loc | 0x04)
   1257       .D8(dwarf2reader::DW_CFA_restore_extended).ULEB128(0x0f9b8a1c)
   1258       .FinishEntry();
   1259 
   1260   {
   1261     InSequence s;
   1262     EXPECT_CALL(handler,
   1263                 Entry(_, fde_start, fde_size, version, "", return_register))
   1264         .WillOnce(Return(true));
   1265     // CIE's CFA rule.
   1266     EXPECT_CALL(handler,
   1267                 ValOffsetRule(fde_start, kCFARegister, 0x56fa0edd, 0x097f78a5))
   1268         .WillOnce(Return(true));
   1269     // CIE's rule for register 0x0f9b8a1c.
   1270     EXPECT_CALL(handler,
   1271                 OffsetRule(fde_start, 0x0f9b8a1c, kCFARegister,
   1272                            0xc979 * data_factor))
   1273         .WillOnce(Return(true));
   1274     // FDE's rule for register 0x0f9b8a1c.
   1275     EXPECT_CALL(handler,
   1276                 OffsetRule(fde_start + 0x3 * code_factor, 0x0f9b8a1c,
   1277                            kCFARegister, 0x3b7b * data_factor))
   1278         .WillOnce(Return(true));
   1279     // Restore CIE's rule for register 0x0f9b8a1c.
   1280     EXPECT_CALL(handler,
   1281                 OffsetRule(fde_start + (0x3 + 0x4) * code_factor, 0x0f9b8a1c,
   1282                            kCFARegister, 0xc979 * data_factor))
   1283         .WillOnce(Return(true));
   1284     EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1285   }
   1286 
   1287   ParseSection(&section);
   1288 }
   1289 
   1290 TEST_F(CFIInsn, DW_CFA_remember_and_restore_state) {
   1291   CFISection section(kLittleEndian, 8);
   1292   StockCIEAndFDE(&section);
   1293 
   1294   // We create a state, save it, modify it, and then restore. We
   1295   // refer to the state that is overridden the restore as the
   1296   // "outgoing" state, and the restored state the "incoming" state.
   1297   //
   1298   // Register         outgoing        incoming        expect
   1299   // 1                offset(N)       no rule         new "same value" rule
   1300   // 2                register(R)     offset(N)       report changed rule
   1301   // 3                offset(N)       offset(M)       report changed offset
   1302   // 4                offset(N)       offset(N)       no report
   1303   // 5                offset(N)       no rule         new "same value" rule
   1304   section
   1305       // Create the "incoming" state, which we will save and later restore.
   1306       .D8(dwarf2reader::DW_CFA_offset | 2).ULEB128(0x9806)
   1307       .D8(dwarf2reader::DW_CFA_offset | 3).ULEB128(0x995d)
   1308       .D8(dwarf2reader::DW_CFA_offset | 4).ULEB128(0x7055)
   1309       .D8(dwarf2reader::DW_CFA_remember_state)
   1310       // Advance to a new instruction; an implementation could legitimately
   1311       // ignore all but the final rule for a given register at a given address.
   1312       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1313       // Create the "outgoing" state, which we will discard.
   1314       .D8(dwarf2reader::DW_CFA_offset | 1).ULEB128(0xea1a)
   1315       .D8(dwarf2reader::DW_CFA_register).ULEB128(2).ULEB128(0x1d2a3767)
   1316       .D8(dwarf2reader::DW_CFA_offset | 3).ULEB128(0xdd29)
   1317       .D8(dwarf2reader::DW_CFA_offset | 5).ULEB128(0xf1ce)
   1318       // At a third address, restore the incoming state.
   1319       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1320       .D8(dwarf2reader::DW_CFA_restore_state)
   1321       .FinishEntry();
   1322 
   1323   uint64 addr = fde_start;
   1324 
   1325   // Expect the incoming rules to be reported.
   1326   EXPECT_CALL(handler, OffsetRule(addr, 2, kCFARegister, 0x9806 * data_factor))
   1327     .InSequence(s).WillOnce(Return(true));
   1328   EXPECT_CALL(handler, OffsetRule(addr, 3, kCFARegister, 0x995d * data_factor))
   1329     .InSequence(s).WillOnce(Return(true));
   1330   EXPECT_CALL(handler, OffsetRule(addr, 4, kCFARegister, 0x7055 * data_factor))
   1331     .InSequence(s).WillOnce(Return(true));
   1332 
   1333   addr += code_factor;
   1334 
   1335   // After the save, we establish the outgoing rule set.
   1336   EXPECT_CALL(handler, OffsetRule(addr, 1, kCFARegister, 0xea1a * data_factor))
   1337     .InSequence(s).WillOnce(Return(true));
   1338   EXPECT_CALL(handler, RegisterRule(addr, 2, 0x1d2a3767))
   1339     .InSequence(s).WillOnce(Return(true));
   1340   EXPECT_CALL(handler, OffsetRule(addr, 3, kCFARegister, 0xdd29 * data_factor))
   1341     .InSequence(s).WillOnce(Return(true));
   1342   EXPECT_CALL(handler, OffsetRule(addr, 5, kCFARegister, 0xf1ce * data_factor))
   1343     .InSequence(s).WillOnce(Return(true));
   1344 
   1345   addr += code_factor;
   1346 
   1347   // Finally, after the restore, expect to see the differences from
   1348   // the outgoing to the incoming rules reported.
   1349   EXPECT_CALL(handler, SameValueRule(addr, 1))
   1350       .InSequence(s).WillOnce(Return(true));
   1351   EXPECT_CALL(handler, OffsetRule(addr, 2, kCFARegister, 0x9806 * data_factor))
   1352       .InSequence(s).WillOnce(Return(true));
   1353   EXPECT_CALL(handler, OffsetRule(addr, 3, kCFARegister, 0x995d * data_factor))
   1354       .InSequence(s).WillOnce(Return(true));
   1355   EXPECT_CALL(handler, SameValueRule(addr, 5))
   1356       .InSequence(s).WillOnce(Return(true));
   1357 
   1358   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1359 
   1360   ParseSection(&section);
   1361 }
   1362 
   1363 // Check that restoring a rule set reports changes to the CFA rule.
   1364 TEST_F(CFIInsn, DW_CFA_remember_and_restore_stateCFA) {
   1365   CFISection section(kBigEndian, 4);
   1366   StockCIEAndFDE(&section);
   1367 
   1368   section
   1369       .D8(dwarf2reader::DW_CFA_remember_state)
   1370       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1371       .D8(dwarf2reader::DW_CFA_def_cfa_offset).ULEB128(0x90481102)
   1372       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1373       .D8(dwarf2reader::DW_CFA_restore_state)
   1374       .FinishEntry();
   1375 
   1376   EXPECT_CALL(handler, ValOffsetRule(fde_start + code_factor, kCFARegister,
   1377                                      cfa_base_register, 0x90481102))
   1378       .InSequence(s).WillOnce(Return(true));
   1379   EXPECT_CALL(handler, ValOffsetRule(fde_start + code_factor * 2, kCFARegister,
   1380                                      cfa_base_register, cfa_offset))
   1381       .InSequence(s).WillOnce(Return(true));
   1382 
   1383   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1384 
   1385   ParseSection(&section);
   1386 }
   1387 
   1388 TEST_F(CFIInsn, DW_CFA_nop) {
   1389   CFISection section(kLittleEndian, 4);
   1390   StockCIEAndFDE(&section);
   1391   section
   1392       .D8(dwarf2reader::DW_CFA_nop)
   1393       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x3fb8d4f1).ULEB128(0x078dc67b)
   1394       .D8(dwarf2reader::DW_CFA_nop)
   1395       .FinishEntry();
   1396 
   1397   EXPECT_CALL(handler,
   1398               ValOffsetRule(fde_start, kCFARegister, 0x3fb8d4f1, 0x078dc67b))
   1399       .InSequence(s).WillOnce(Return(true));
   1400   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1401 
   1402   ParseSection(&section);
   1403 }
   1404 
   1405 TEST_F(CFIInsn, DW_CFA_GNU_window_save) {
   1406   CFISection section(kBigEndian, 4);
   1407   StockCIEAndFDE(&section);
   1408   section
   1409       .D8(dwarf2reader::DW_CFA_GNU_window_save)
   1410       .FinishEntry();
   1411 
   1412   // Don't include all the rules in any particular sequence.
   1413 
   1414   // The caller's %o0-%o7 have become the callee's %i0-%i7. This is
   1415   // the GCC register numbering.
   1416   for (int i = 8; i < 16; i++)
   1417     EXPECT_CALL(handler, RegisterRule(fde_start, i, i + 16))
   1418         .WillOnce(Return(true));
   1419   // The caller's %l0-%l7 and %i0-%i7 have been saved at the top of
   1420   // its frame.
   1421   for (int i = 16; i < 32; i++)
   1422     EXPECT_CALL(handler, OffsetRule(fde_start, i, kCFARegister, (i-16) * 4))
   1423         .WillOnce(Return(true));
   1424 
   1425   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1426 
   1427   ParseSection(&section);
   1428 }
   1429 
   1430 TEST_F(CFIInsn, DW_CFA_GNU_args_size) {
   1431   CFISection section(kLittleEndian, 8);
   1432   StockCIEAndFDE(&section);
   1433   section
   1434       .D8(dwarf2reader::DW_CFA_GNU_args_size).ULEB128(0xeddfa520)
   1435       // Verify that we see this, meaning we parsed the above properly.
   1436       .D8(dwarf2reader::DW_CFA_offset | 0x23).ULEB128(0x269)
   1437       .FinishEntry();
   1438 
   1439   EXPECT_CALL(handler,
   1440               OffsetRule(fde_start, 0x23, kCFARegister, 0x269 * data_factor))
   1441       .InSequence(s).WillOnce(Return(true));
   1442   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1443 
   1444   ParseSection(&section);
   1445 }
   1446 
   1447 TEST_F(CFIInsn, DW_CFA_GNU_negative_offset_extended) {
   1448   CFISection section(kLittleEndian, 4);
   1449   StockCIEAndFDE(&section);
   1450   section
   1451       .D8(dwarf2reader::DW_CFA_GNU_negative_offset_extended)
   1452       .ULEB128(0x430cc87a).ULEB128(0x613)
   1453       .FinishEntry();
   1454 
   1455   EXPECT_CALL(handler,
   1456               OffsetRule(fde_start, 0x430cc87a,
   1457                          kCFARegister, -0x613 * data_factor))
   1458       .InSequence(s).WillOnce(Return(true));
   1459   EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
   1460 
   1461   ParseSection(&section);
   1462 }
   1463 
   1464 // Three FDEs: skip the second
   1465 TEST_F(CFIInsn, SkipFDE) {
   1466   CFISection section(kBigEndian, 4);
   1467   Label cie;
   1468   section
   1469       // CIE, used by all FDEs.
   1470       .Mark(&cie)
   1471       .CIEHeader(0x010269f2, 0x9177, 0xedca5849, 2, "")
   1472       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(0x42ed390b).ULEB128(0x98f43aad)
   1473       .FinishEntry()
   1474       // First FDE.
   1475       .FDEHeader(cie, 0xa870ebdd, 0x60f6aa4)
   1476       .D8(dwarf2reader::DW_CFA_register).ULEB128(0x3a860351).ULEB128(0x6c9a6bcf)
   1477       .FinishEntry()
   1478       // Second FDE.
   1479       .FDEHeader(cie, 0xc534f7c0, 0xf6552e9, true /* dwarf64 */)
   1480       .D8(dwarf2reader::DW_CFA_register).ULEB128(0x1b62c234).ULEB128(0x26586b18)
   1481       .FinishEntry()
   1482       // Third FDE.
   1483       .FDEHeader(cie, 0xf681cfc8, 0x7e4594e)
   1484       .D8(dwarf2reader::DW_CFA_register).ULEB128(0x26c53934).ULEB128(0x18eeb8a4)
   1485       .FinishEntry();
   1486 
   1487   {
   1488     InSequence s;
   1489 
   1490     // Process the first FDE.
   1491     EXPECT_CALL(handler, Entry(_, 0xa870ebdd, 0x60f6aa4, 2, "", 0xedca5849))
   1492         .WillOnce(Return(true));
   1493     EXPECT_CALL(handler, ValOffsetRule(0xa870ebdd, kCFARegister,
   1494                                        0x42ed390b, 0x98f43aad))
   1495         .WillOnce(Return(true));
   1496     EXPECT_CALL(handler, RegisterRule(0xa870ebdd, 0x3a860351, 0x6c9a6bcf))
   1497         .WillOnce(Return(true));
   1498     EXPECT_CALL(handler, End())
   1499         .WillOnce(Return(true));
   1500 
   1501     // Skip the second FDE.
   1502     EXPECT_CALL(handler, Entry(_, 0xc534f7c0, 0xf6552e9, 2, "", 0xedca5849))
   1503         .WillOnce(Return(false));
   1504 
   1505     // Process the third FDE.
   1506     EXPECT_CALL(handler, Entry(_, 0xf681cfc8, 0x7e4594e, 2, "", 0xedca5849))
   1507         .WillOnce(Return(true));
   1508     EXPECT_CALL(handler, ValOffsetRule(0xf681cfc8, kCFARegister,
   1509                                        0x42ed390b, 0x98f43aad))
   1510         .WillOnce(Return(true));
   1511     EXPECT_CALL(handler, RegisterRule(0xf681cfc8, 0x26c53934, 0x18eeb8a4))
   1512         .WillOnce(Return(true));
   1513     EXPECT_CALL(handler, End())
   1514         .WillOnce(Return(true));
   1515   }
   1516 
   1517   ParseSection(&section);
   1518 }
   1519 
   1520 // Quit processing in the middle of an entry's instructions.
   1521 TEST_F(CFIInsn, QuitMidentry) {
   1522   CFISection section(kLittleEndian, 8);
   1523   StockCIEAndFDE(&section);
   1524   section
   1525       .D8(dwarf2reader::DW_CFA_register).ULEB128(0xe0cf850d).ULEB128(0x15aab431)
   1526       .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x46750aa5).Block("meat")
   1527       .FinishEntry();
   1528 
   1529   EXPECT_CALL(handler, RegisterRule(fde_start, 0xe0cf850d, 0x15aab431))
   1530       .InSequence(s).WillOnce(Return(false));
   1531   EXPECT_CALL(handler, End())
   1532       .InSequence(s).WillOnce(Return(true));
   1533 
   1534   ParseSection(&section, false);
   1535 }
   1536 
   1537 class CFIRestore: public CFIInsnFixture, public Test { };
   1538 
   1539 TEST_F(CFIRestore, RestoreUndefinedRuleUnchanged) {
   1540   CFISection section(kLittleEndian, 4);
   1541   StockCIEAndFDE(&section);
   1542   section
   1543       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x0bac878e)
   1544       .D8(dwarf2reader::DW_CFA_remember_state)
   1545       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1546       .D8(dwarf2reader::DW_CFA_restore_state)
   1547       .FinishEntry();
   1548 
   1549   EXPECT_CALL(handler, UndefinedRule(fde_start, 0x0bac878e))
   1550       .InSequence(s).WillOnce(Return(true));
   1551   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1552 
   1553   ParseSection(&section);
   1554 }
   1555 
   1556 TEST_F(CFIRestore, RestoreUndefinedRuleChanged) {
   1557   CFISection section(kLittleEndian, 4);
   1558   StockCIEAndFDE(&section);
   1559   section
   1560       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x7dedff5f)
   1561       .D8(dwarf2reader::DW_CFA_remember_state)
   1562       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1563       .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0x7dedff5f)
   1564       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1565       .D8(dwarf2reader::DW_CFA_restore_state)
   1566       .FinishEntry();
   1567 
   1568   EXPECT_CALL(handler, UndefinedRule(fde_start, 0x7dedff5f))
   1569       .InSequence(s).WillOnce(Return(true));
   1570   EXPECT_CALL(handler, SameValueRule(fde_start + code_factor, 0x7dedff5f))
   1571       .InSequence(s).WillOnce(Return(true));
   1572   EXPECT_CALL(handler, UndefinedRule(fde_start + 2 * code_factor, 0x7dedff5f))
   1573       .InSequence(s).WillOnce(Return(true));
   1574   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1575 
   1576   ParseSection(&section);
   1577 }
   1578 
   1579 TEST_F(CFIRestore, RestoreSameValueRuleUnchanged) {
   1580   CFISection section(kLittleEndian, 4);
   1581   StockCIEAndFDE(&section);
   1582   section
   1583       .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0xadbc9b3a)
   1584       .D8(dwarf2reader::DW_CFA_remember_state)
   1585       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1586       .D8(dwarf2reader::DW_CFA_restore_state)
   1587       .FinishEntry();
   1588 
   1589   EXPECT_CALL(handler, SameValueRule(fde_start, 0xadbc9b3a))
   1590       .InSequence(s).WillOnce(Return(true));
   1591   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1592 
   1593   ParseSection(&section);
   1594 }
   1595 
   1596 TEST_F(CFIRestore, RestoreSameValueRuleChanged) {
   1597   CFISection section(kLittleEndian, 4);
   1598   StockCIEAndFDE(&section);
   1599   section
   1600       .D8(dwarf2reader::DW_CFA_same_value).ULEB128(0x3d90dcb5)
   1601       .D8(dwarf2reader::DW_CFA_remember_state)
   1602       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1603       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x3d90dcb5)
   1604       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1605       .D8(dwarf2reader::DW_CFA_restore_state)
   1606       .FinishEntry();
   1607 
   1608   EXPECT_CALL(handler, SameValueRule(fde_start, 0x3d90dcb5))
   1609       .InSequence(s).WillOnce(Return(true));
   1610   EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0x3d90dcb5))
   1611       .InSequence(s).WillOnce(Return(true));
   1612   EXPECT_CALL(handler, SameValueRule(fde_start + 2 * code_factor, 0x3d90dcb5))
   1613       .InSequence(s).WillOnce(Return(true));
   1614   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1615 
   1616   ParseSection(&section);
   1617 }
   1618 
   1619 TEST_F(CFIRestore, RestoreOffsetRuleUnchanged) {
   1620   CFISection section(kLittleEndian, 4);
   1621   StockCIEAndFDE(&section);
   1622   section
   1623       .D8(dwarf2reader::DW_CFA_offset | 0x14).ULEB128(0xb6f)
   1624       .D8(dwarf2reader::DW_CFA_remember_state)
   1625       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1626       .D8(dwarf2reader::DW_CFA_restore_state)
   1627       .FinishEntry();
   1628 
   1629   EXPECT_CALL(handler, OffsetRule(fde_start, 0x14,
   1630                                   kCFARegister, 0xb6f * data_factor))
   1631       .InSequence(s).WillOnce(Return(true));
   1632   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1633 
   1634   ParseSection(&section);
   1635 }
   1636 
   1637 TEST_F(CFIRestore, RestoreOffsetRuleChanged) {
   1638   CFISection section(kLittleEndian, 4);
   1639   StockCIEAndFDE(&section);
   1640   section
   1641       .D8(dwarf2reader::DW_CFA_offset | 0x21).ULEB128(0xeb7)
   1642       .D8(dwarf2reader::DW_CFA_remember_state)
   1643       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1644       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x21)
   1645       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1646       .D8(dwarf2reader::DW_CFA_restore_state)
   1647       .FinishEntry();
   1648 
   1649   EXPECT_CALL(handler, OffsetRule(fde_start, 0x21,
   1650                                   kCFARegister, 0xeb7 * data_factor))
   1651       .InSequence(s).WillOnce(Return(true));
   1652   EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0x21))
   1653       .InSequence(s).WillOnce(Return(true));
   1654   EXPECT_CALL(handler, OffsetRule(fde_start + 2 * code_factor, 0x21,
   1655                                   kCFARegister, 0xeb7 * data_factor))
   1656       .InSequence(s).WillOnce(Return(true));
   1657   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1658 
   1659   ParseSection(&section);
   1660 }
   1661 
   1662 TEST_F(CFIRestore, RestoreOffsetRuleChangedOffset) {
   1663   CFISection section(kLittleEndian, 4);
   1664   StockCIEAndFDE(&section);
   1665   section
   1666       .D8(dwarf2reader::DW_CFA_offset | 0x21).ULEB128(0x134)
   1667       .D8(dwarf2reader::DW_CFA_remember_state)
   1668       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1669       .D8(dwarf2reader::DW_CFA_offset | 0x21).ULEB128(0xf4f)
   1670       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1671       .D8(dwarf2reader::DW_CFA_restore_state)
   1672       .FinishEntry();
   1673 
   1674   EXPECT_CALL(handler, OffsetRule(fde_start, 0x21,
   1675                                   kCFARegister, 0x134 * data_factor))
   1676       .InSequence(s).WillOnce(Return(true));
   1677   EXPECT_CALL(handler, OffsetRule(fde_start + code_factor, 0x21,
   1678                                   kCFARegister, 0xf4f * data_factor))
   1679       .InSequence(s).WillOnce(Return(true));
   1680   EXPECT_CALL(handler, OffsetRule(fde_start + 2 * code_factor, 0x21,
   1681                                   kCFARegister, 0x134 * data_factor))
   1682       .InSequence(s).WillOnce(Return(true));
   1683   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1684 
   1685   ParseSection(&section);
   1686 }
   1687 
   1688 TEST_F(CFIRestore, RestoreValOffsetRuleUnchanged) {
   1689   CFISection section(kLittleEndian, 4);
   1690   StockCIEAndFDE(&section);
   1691   section
   1692       .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x829caee6).ULEB128(0xe4c)
   1693       .D8(dwarf2reader::DW_CFA_remember_state)
   1694       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1695       .D8(dwarf2reader::DW_CFA_restore_state)
   1696       .FinishEntry();
   1697 
   1698   EXPECT_CALL(handler, ValOffsetRule(fde_start, 0x829caee6,
   1699                                   kCFARegister, 0xe4c * data_factor))
   1700       .InSequence(s).WillOnce(Return(true));
   1701   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1702 
   1703   ParseSection(&section);
   1704 }
   1705 
   1706 TEST_F(CFIRestore, RestoreValOffsetRuleChanged) {
   1707   CFISection section(kLittleEndian, 4);
   1708   StockCIEAndFDE(&section);
   1709   section
   1710       .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0xf17c36d6).ULEB128(0xeb7)
   1711       .D8(dwarf2reader::DW_CFA_remember_state)
   1712       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1713       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xf17c36d6)
   1714       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1715       .D8(dwarf2reader::DW_CFA_restore_state)
   1716       .FinishEntry();
   1717 
   1718   EXPECT_CALL(handler, ValOffsetRule(fde_start, 0xf17c36d6,
   1719                                   kCFARegister, 0xeb7 * data_factor))
   1720       .InSequence(s).WillOnce(Return(true));
   1721   EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xf17c36d6))
   1722       .InSequence(s).WillOnce(Return(true));
   1723   EXPECT_CALL(handler, ValOffsetRule(fde_start + 2 * code_factor, 0xf17c36d6,
   1724                                   kCFARegister, 0xeb7 * data_factor))
   1725       .InSequence(s).WillOnce(Return(true));
   1726   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1727 
   1728   ParseSection(&section);
   1729 }
   1730 
   1731 TEST_F(CFIRestore, RestoreValOffsetRuleChangedValOffset) {
   1732   CFISection section(kLittleEndian, 4);
   1733   StockCIEAndFDE(&section);
   1734   section
   1735       .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x2cf0ab1b).ULEB128(0x562)
   1736       .D8(dwarf2reader::DW_CFA_remember_state)
   1737       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1738       .D8(dwarf2reader::DW_CFA_val_offset).ULEB128(0x2cf0ab1b).ULEB128(0xe88)
   1739       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1740       .D8(dwarf2reader::DW_CFA_restore_state)
   1741       .FinishEntry();
   1742 
   1743   EXPECT_CALL(handler, ValOffsetRule(fde_start, 0x2cf0ab1b,
   1744                                   kCFARegister, 0x562 * data_factor))
   1745       .InSequence(s).WillOnce(Return(true));
   1746   EXPECT_CALL(handler, ValOffsetRule(fde_start + code_factor, 0x2cf0ab1b,
   1747                                   kCFARegister, 0xe88 * data_factor))
   1748       .InSequence(s).WillOnce(Return(true));
   1749   EXPECT_CALL(handler, ValOffsetRule(fde_start + 2 * code_factor, 0x2cf0ab1b,
   1750                                   kCFARegister, 0x562 * data_factor))
   1751       .InSequence(s).WillOnce(Return(true));
   1752   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1753 
   1754   ParseSection(&section);
   1755 }
   1756 
   1757 TEST_F(CFIRestore, RestoreRegisterRuleUnchanged) {
   1758   CFISection section(kLittleEndian, 4);
   1759   StockCIEAndFDE(&section);
   1760   section
   1761       .D8(dwarf2reader::DW_CFA_register).ULEB128(0x77514acc).ULEB128(0x464de4ce)
   1762       .D8(dwarf2reader::DW_CFA_remember_state)
   1763       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1764       .D8(dwarf2reader::DW_CFA_restore_state)
   1765       .FinishEntry();
   1766 
   1767   EXPECT_CALL(handler, RegisterRule(fde_start, 0x77514acc, 0x464de4ce))
   1768       .InSequence(s).WillOnce(Return(true));
   1769   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1770 
   1771   ParseSection(&section);
   1772 }
   1773 
   1774 TEST_F(CFIRestore, RestoreRegisterRuleChanged) {
   1775   CFISection section(kLittleEndian, 4);
   1776   StockCIEAndFDE(&section);
   1777   section
   1778       .D8(dwarf2reader::DW_CFA_register).ULEB128(0xe39acce5).ULEB128(0x095f1559)
   1779       .D8(dwarf2reader::DW_CFA_remember_state)
   1780       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1781       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xe39acce5)
   1782       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1783       .D8(dwarf2reader::DW_CFA_restore_state)
   1784       .FinishEntry();
   1785 
   1786   EXPECT_CALL(handler, RegisterRule(fde_start, 0xe39acce5, 0x095f1559))
   1787       .InSequence(s).WillOnce(Return(true));
   1788   EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xe39acce5))
   1789       .InSequence(s).WillOnce(Return(true));
   1790   EXPECT_CALL(handler, RegisterRule(fde_start + 2 * code_factor, 0xe39acce5,
   1791                                     0x095f1559))
   1792       .InSequence(s).WillOnce(Return(true));
   1793   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1794 
   1795   ParseSection(&section);
   1796 }
   1797 
   1798 TEST_F(CFIRestore, RestoreRegisterRuleChangedRegister) {
   1799   CFISection section(kLittleEndian, 4);
   1800   StockCIEAndFDE(&section);
   1801   section
   1802       .D8(dwarf2reader::DW_CFA_register).ULEB128(0xd40e21b1).ULEB128(0x16607d6a)
   1803       .D8(dwarf2reader::DW_CFA_remember_state)
   1804       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1805       .D8(dwarf2reader::DW_CFA_register).ULEB128(0xd40e21b1).ULEB128(0xbabb4742)
   1806       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1807       .D8(dwarf2reader::DW_CFA_restore_state)
   1808       .FinishEntry();
   1809 
   1810   EXPECT_CALL(handler, RegisterRule(fde_start, 0xd40e21b1, 0x16607d6a))
   1811       .InSequence(s).WillOnce(Return(true));
   1812   EXPECT_CALL(handler, RegisterRule(fde_start + code_factor, 0xd40e21b1,
   1813                                     0xbabb4742))
   1814       .InSequence(s).WillOnce(Return(true));
   1815   EXPECT_CALL(handler, RegisterRule(fde_start + 2 * code_factor, 0xd40e21b1,
   1816                                     0x16607d6a))
   1817       .InSequence(s).WillOnce(Return(true));
   1818   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1819 
   1820   ParseSection(&section);
   1821 }
   1822 
   1823 TEST_F(CFIRestore, RestoreExpressionRuleUnchanged) {
   1824   CFISection section(kLittleEndian, 4);
   1825   StockCIEAndFDE(&section);
   1826   section
   1827       .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x666ae152).Block("dwarf")
   1828       .D8(dwarf2reader::DW_CFA_remember_state)
   1829       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1830       .D8(dwarf2reader::DW_CFA_restore_state)
   1831       .FinishEntry();
   1832 
   1833   EXPECT_CALL(handler, ExpressionRule(fde_start, 0x666ae152, "dwarf"))
   1834       .InSequence(s).WillOnce(Return(true));
   1835   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1836 
   1837   ParseSection(&section);
   1838 }
   1839 
   1840 TEST_F(CFIRestore, RestoreExpressionRuleChanged) {
   1841   CFISection section(kLittleEndian, 4);
   1842   StockCIEAndFDE(&section);
   1843   section
   1844       .D8(dwarf2reader::DW_CFA_expression).ULEB128(0xb5ca5c46).Block("elf")
   1845       .D8(dwarf2reader::DW_CFA_remember_state)
   1846       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1847       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xb5ca5c46)
   1848       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1849       .D8(dwarf2reader::DW_CFA_restore_state)
   1850       .FinishEntry();
   1851 
   1852   EXPECT_CALL(handler, ExpressionRule(fde_start, 0xb5ca5c46, "elf"))
   1853       .InSequence(s).WillOnce(Return(true));
   1854   EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xb5ca5c46))
   1855       .InSequence(s).WillOnce(Return(true));
   1856   EXPECT_CALL(handler, ExpressionRule(fde_start + 2 * code_factor, 0xb5ca5c46,
   1857                                       "elf"))
   1858       .InSequence(s).WillOnce(Return(true));
   1859   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1860 
   1861   ParseSection(&section);
   1862 }
   1863 
   1864 TEST_F(CFIRestore, RestoreExpressionRuleChangedExpression) {
   1865   CFISection section(kLittleEndian, 4);
   1866   StockCIEAndFDE(&section);
   1867   section
   1868       .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x500f5739).Block("smurf")
   1869       .D8(dwarf2reader::DW_CFA_remember_state)
   1870       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1871       .D8(dwarf2reader::DW_CFA_expression).ULEB128(0x500f5739).Block("orc")
   1872       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1873       .D8(dwarf2reader::DW_CFA_restore_state)
   1874       .FinishEntry();
   1875 
   1876   EXPECT_CALL(handler, ExpressionRule(fde_start, 0x500f5739, "smurf"))
   1877       .InSequence(s).WillOnce(Return(true));
   1878   EXPECT_CALL(handler, ExpressionRule(fde_start + code_factor, 0x500f5739,
   1879                                       "orc"))
   1880       .InSequence(s).WillOnce(Return(true));
   1881   // Expectations are not wishes.
   1882   EXPECT_CALL(handler, ExpressionRule(fde_start + 2 * code_factor, 0x500f5739,
   1883                                       "smurf"))
   1884       .InSequence(s).WillOnce(Return(true));
   1885   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1886 
   1887   ParseSection(&section);
   1888 }
   1889 
   1890 TEST_F(CFIRestore, RestoreValExpressionRuleUnchanged) {
   1891   CFISection section(kLittleEndian, 4);
   1892   StockCIEAndFDE(&section);
   1893   section
   1894       .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0x666ae152)
   1895       .Block("hideous")
   1896       .D8(dwarf2reader::DW_CFA_remember_state)
   1897       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1898       .D8(dwarf2reader::DW_CFA_restore_state)
   1899       .FinishEntry();
   1900 
   1901   EXPECT_CALL(handler, ValExpressionRule(fde_start, 0x666ae152, "hideous"))
   1902       .InSequence(s).WillOnce(Return(true));
   1903   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1904 
   1905   ParseSection(&section);
   1906 }
   1907 
   1908 TEST_F(CFIRestore, RestoreValExpressionRuleChanged) {
   1909   CFISection section(kLittleEndian, 4);
   1910   StockCIEAndFDE(&section);
   1911   section
   1912       .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0xb5ca5c46)
   1913       .Block("revolting")
   1914       .D8(dwarf2reader::DW_CFA_remember_state)
   1915       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1916       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0xb5ca5c46)
   1917       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1918       .D8(dwarf2reader::DW_CFA_restore_state)
   1919       .FinishEntry();
   1920 
   1921   PERHAPS_WRITE_DEBUG_FRAME_FILE("RestoreValExpressionRuleChanged", section);
   1922 
   1923   EXPECT_CALL(handler, ValExpressionRule(fde_start, 0xb5ca5c46, "revolting"))
   1924       .InSequence(s).WillOnce(Return(true));
   1925   EXPECT_CALL(handler, UndefinedRule(fde_start + code_factor, 0xb5ca5c46))
   1926       .InSequence(s).WillOnce(Return(true));
   1927   EXPECT_CALL(handler, ValExpressionRule(fde_start + 2 * code_factor, 0xb5ca5c46,
   1928                                       "revolting"))
   1929       .InSequence(s).WillOnce(Return(true));
   1930   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1931 
   1932   ParseSection(&section);
   1933 }
   1934 
   1935 TEST_F(CFIRestore, RestoreValExpressionRuleChangedValExpression) {
   1936   CFISection section(kLittleEndian, 4);
   1937   StockCIEAndFDE(&section);
   1938   section
   1939       .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0x500f5739)
   1940       .Block("repulsive")
   1941       .D8(dwarf2reader::DW_CFA_remember_state)
   1942       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1943       .D8(dwarf2reader::DW_CFA_val_expression).ULEB128(0x500f5739)
   1944       .Block("nauseous")
   1945       .D8(dwarf2reader::DW_CFA_advance_loc | 1)
   1946       .D8(dwarf2reader::DW_CFA_restore_state)
   1947       .FinishEntry();
   1948 
   1949   PERHAPS_WRITE_DEBUG_FRAME_FILE("RestoreValExpressionRuleChangedValExpression",
   1950                                  section);
   1951 
   1952   EXPECT_CALL(handler, ValExpressionRule(fde_start, 0x500f5739, "repulsive"))
   1953       .InSequence(s).WillOnce(Return(true));
   1954   EXPECT_CALL(handler, ValExpressionRule(fde_start + code_factor, 0x500f5739,
   1955                                       "nauseous"))
   1956       .InSequence(s).WillOnce(Return(true));
   1957   // Expectations are not wishes.
   1958   EXPECT_CALL(handler, ValExpressionRule(fde_start + 2 * code_factor, 0x500f5739,
   1959                                       "repulsive"))
   1960       .InSequence(s).WillOnce(Return(true));
   1961   EXPECT_CALL(handler, End()).WillOnce(Return(true));
   1962 
   1963   ParseSection(&section);
   1964 }
   1965 
   1966 struct EHFrameFixture: public CFIInsnFixture {
   1967   EHFrameFixture()
   1968       : CFIInsnFixture(), section(kBigEndian, 4, true) {
   1969     encoded_pointer_bases.cfi  = 0x7f496cb2;
   1970     encoded_pointer_bases.text = 0x540f67b6;
   1971     encoded_pointer_bases.data = 0xe3eab768;
   1972     section.SetEncodedPointerBases(encoded_pointer_bases);
   1973   }
   1974   CFISection section;
   1975   CFISection::EncodedPointerBases encoded_pointer_bases;
   1976 
   1977   // Parse CFIInsnFixture::ParseSection, but parse the section as
   1978   // .eh_frame data, supplying stock base addresses.
   1979   void ParseEHFrameSection(CFISection *section, bool succeeds = true) {
   1980     EXPECT_TRUE(section->ContainsEHFrame());
   1981     string contents;
   1982     EXPECT_TRUE(section->GetContents(&contents));
   1983     dwarf2reader::Endianness endianness;
   1984     if (section->endianness() == kBigEndian)
   1985       endianness = ENDIANNESS_BIG;
   1986     else {
   1987       assert(section->endianness() == kLittleEndian);
   1988       endianness = ENDIANNESS_LITTLE;
   1989     }
   1990     ByteReader byte_reader(endianness);
   1991     byte_reader.SetAddressSize(section->AddressSize());
   1992     byte_reader.SetCFIDataBase(encoded_pointer_bases.cfi, contents.data());
   1993     byte_reader.SetTextBase(encoded_pointer_bases.text);
   1994     byte_reader.SetDataBase(encoded_pointer_bases.data);
   1995     CallFrameInfo parser(contents.data(), contents.size(),
   1996                          &byte_reader, &handler, &reporter, true);
   1997     if (succeeds)
   1998       EXPECT_TRUE(parser.Start());
   1999     else
   2000       EXPECT_FALSE(parser.Start());
   2001   }
   2002 
   2003 };
   2004 
   2005 class EHFrame: public EHFrameFixture, public Test { };
   2006 
   2007 // A simple CIE, an FDE, and a terminator.
   2008 TEST_F(EHFrame, Terminator) {
   2009   Label cie;
   2010   section
   2011       .Mark(&cie)
   2012       .CIEHeader(9968, 2466, 67, 1, "")
   2013       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(3772).ULEB128(1372)
   2014       .FinishEntry()
   2015       .FDEHeader(cie, 0x848037a1, 0x7b30475e)
   2016       .D8(dwarf2reader::DW_CFA_set_loc).D32(0x17713850)
   2017       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(5721)
   2018       .FinishEntry()
   2019       .D32(0)                           // Terminate the sequence.
   2020       // This FDE should be ignored.
   2021       .FDEHeader(cie, 0xf19629fe, 0x439fb09b)
   2022       .FinishEntry();
   2023 
   2024   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.Terminator", section);
   2025 
   2026   EXPECT_CALL(handler, Entry(_, 0x848037a1, 0x7b30475e, 1, "", 67))
   2027       .InSequence(s).WillOnce(Return(true));
   2028   EXPECT_CALL(handler, ValOffsetRule(0x848037a1, kCFARegister, 3772, 1372))
   2029       .InSequence(s).WillOnce(Return(true));
   2030   EXPECT_CALL(handler, UndefinedRule(0x17713850, 5721))
   2031       .InSequence(s).WillOnce(Return(true));
   2032   EXPECT_CALL(handler, End())
   2033       .InSequence(s).WillOnce(Return(true));
   2034   EXPECT_CALL(reporter, EarlyEHTerminator(_))
   2035       .InSequence(s).WillOnce(Return());
   2036 
   2037   ParseEHFrameSection(&section);
   2038 }
   2039 
   2040 // The parser should recognize the Linux Standards Base 'z' augmentations.
   2041 TEST_F(EHFrame, SimpleFDE) {
   2042   DwarfPointerEncoding lsda_encoding =
   2043       DwarfPointerEncoding(dwarf2reader::DW_EH_PE_indirect
   2044                            | dwarf2reader::DW_EH_PE_datarel
   2045                            | dwarf2reader::DW_EH_PE_sdata2);
   2046   DwarfPointerEncoding fde_encoding =
   2047       DwarfPointerEncoding(dwarf2reader::DW_EH_PE_textrel
   2048                            | dwarf2reader::DW_EH_PE_udata2);
   2049 
   2050   section.SetPointerEncoding(fde_encoding);
   2051   section.SetEncodedPointerBases(encoded_pointer_bases);
   2052   Label cie;
   2053   section
   2054       .Mark(&cie)
   2055       .CIEHeader(4873, 7012, 100, 1, "zSLPR")
   2056       .ULEB128(7)                                // Augmentation data length
   2057       .D8(lsda_encoding)                         // LSDA pointer format
   2058       .D8(dwarf2reader::DW_EH_PE_pcrel)          // personality pointer format
   2059       .EncodedPointer(0x97baa00, dwarf2reader::DW_EH_PE_pcrel) // and value
   2060       .D8(fde_encoding)                          // FDE pointer format
   2061       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(6706).ULEB128(31)
   2062       .FinishEntry()
   2063       .FDEHeader(cie, 0x540f6b56, 0xf686)
   2064       .ULEB128(2)                                // Augmentation data length
   2065       .EncodedPointer(0xe3eab475, lsda_encoding) // LSDA pointer, signed
   2066       .D8(dwarf2reader::DW_CFA_set_loc)
   2067       .EncodedPointer(0x540fa4ce, fde_encoding)
   2068       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(0x675e)
   2069       .FinishEntry()
   2070       .D32(0);                                   // terminator
   2071 
   2072   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.SimpleFDE", section);
   2073 
   2074   EXPECT_CALL(handler, Entry(_, 0x540f6b56, 0xf686, 1, "zSLPR", 100))
   2075       .InSequence(s).WillOnce(Return(true));
   2076   EXPECT_CALL(handler, PersonalityRoutine(0x97baa00, false))
   2077       .InSequence(s).WillOnce(Return(true));
   2078   EXPECT_CALL(handler, LanguageSpecificDataArea(0xe3eab475, true))
   2079       .InSequence(s).WillOnce(Return(true));
   2080   EXPECT_CALL(handler, SignalHandler())
   2081       .InSequence(s).WillOnce(Return(true));
   2082   EXPECT_CALL(handler, ValOffsetRule(0x540f6b56, kCFARegister, 6706, 31))
   2083       .InSequence(s).WillOnce(Return(true));
   2084   EXPECT_CALL(handler, UndefinedRule(0x540fa4ce, 0x675e))
   2085       .InSequence(s).WillOnce(Return(true));
   2086   EXPECT_CALL(handler, End())
   2087       .InSequence(s).WillOnce(Return(true));
   2088 
   2089   ParseEHFrameSection(&section);
   2090 }
   2091 
   2092 // Check that we can handle an empty 'z' augmentation.
   2093 TEST_F(EHFrame, EmptyZ) {
   2094   Label cie;
   2095   section
   2096       .Mark(&cie)
   2097       .CIEHeader(5955, 5805, 228, 1, "z")
   2098       .ULEB128(0)                                // Augmentation data length
   2099       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(3629).ULEB128(247)
   2100       .FinishEntry()
   2101       .FDEHeader(cie, 0xda007738, 0xfb55c641)
   2102       .ULEB128(0)                                // Augmentation data length
   2103       .D8(dwarf2reader::DW_CFA_advance_loc1).D8(11)
   2104       .D8(dwarf2reader::DW_CFA_undefined).ULEB128(3769)
   2105       .FinishEntry();
   2106 
   2107   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.EmptyZ", section);
   2108 
   2109   EXPECT_CALL(handler, Entry(_, 0xda007738, 0xfb55c641, 1, "z", 228))
   2110       .InSequence(s).WillOnce(Return(true));
   2111   EXPECT_CALL(handler, ValOffsetRule(0xda007738, kCFARegister, 3629, 247))
   2112       .InSequence(s).WillOnce(Return(true));
   2113   EXPECT_CALL(handler, UndefinedRule(0xda007738 + 11 * 5955, 3769))
   2114       .InSequence(s).WillOnce(Return(true));
   2115   EXPECT_CALL(handler, End())
   2116       .InSequence(s).WillOnce(Return(true));
   2117 
   2118   ParseEHFrameSection(&section);
   2119 }
   2120 
   2121 // Check that we recognize bad 'z' augmentation characters.
   2122 TEST_F(EHFrame, BadZ) {
   2123   Label cie;
   2124   section
   2125       .Mark(&cie)
   2126       .CIEHeader(6937, 1045, 142, 1, "zQ")
   2127       .ULEB128(0)                                // Augmentation data length
   2128       .D8(dwarf2reader::DW_CFA_def_cfa).ULEB128(9006).ULEB128(7725)
   2129       .FinishEntry()
   2130       .FDEHeader(cie, 0x1293efa8, 0x236f53f2)
   2131       .ULEB128(0)                                // Augmentation data length
   2132       .D8(dwarf2reader::DW_CFA_advance_loc | 12)
   2133       .D8(dwarf2reader::DW_CFA_register).ULEB128(5667).ULEB128(3462)
   2134       .FinishEntry();
   2135 
   2136   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.BadZ", section);
   2137 
   2138   EXPECT_CALL(reporter, UnrecognizedAugmentation(_, "zQ"))
   2139       .WillOnce(Return());
   2140 
   2141   ParseEHFrameSection(&section, false);
   2142 }
   2143 
   2144 TEST_F(EHFrame, zL) {
   2145   Label cie;
   2146   DwarfPointerEncoding lsda_encoding =
   2147       DwarfPointerEncoding(dwarf2reader::DW_EH_PE_funcrel
   2148                            | dwarf2reader::DW_EH_PE_udata2);
   2149   section
   2150       .Mark(&cie)
   2151       .CIEHeader(9285, 9959, 54, 1, "zL")
   2152       .ULEB128(1)                       // Augmentation data length
   2153       .D8(lsda_encoding)                // encoding for LSDA pointer in FDE
   2154 
   2155       .FinishEntry()
   2156       .FDEHeader(cie, 0xd40091aa, 0x9aa6e746)
   2157       .ULEB128(2)                       // Augmentation data length
   2158       .EncodedPointer(0xd40099cd, lsda_encoding) // LSDA pointer
   2159       .FinishEntry()
   2160       .D32(0);                                   // terminator
   2161 
   2162   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zL", section);
   2163 
   2164   EXPECT_CALL(handler, Entry(_, 0xd40091aa, 0x9aa6e746, 1, "zL", 54))
   2165       .InSequence(s).WillOnce(Return(true));
   2166   EXPECT_CALL(handler, LanguageSpecificDataArea(0xd40099cd, false))
   2167       .InSequence(s).WillOnce(Return(true));
   2168   EXPECT_CALL(handler, End())
   2169       .InSequence(s).WillOnce(Return(true));
   2170 
   2171   ParseEHFrameSection(&section);
   2172 }
   2173 
   2174 TEST_F(EHFrame, zP) {
   2175   Label cie;
   2176   DwarfPointerEncoding personality_encoding =
   2177       DwarfPointerEncoding(dwarf2reader::DW_EH_PE_datarel
   2178                            | dwarf2reader::DW_EH_PE_udata2);
   2179   section
   2180       .Mark(&cie)
   2181       .CIEHeader(1097, 6313, 17, 1, "zP")
   2182       .ULEB128(3)                  // Augmentation data length
   2183       .D8(personality_encoding)    // encoding for personality routine
   2184       .EncodedPointer(0xe3eaccac, personality_encoding) // value
   2185       .FinishEntry()
   2186       .FDEHeader(cie, 0x0c8350c9, 0xbef11087)
   2187       .ULEB128(0)                       // Augmentation data length
   2188       .FinishEntry()
   2189       .D32(0);                                   // terminator
   2190 
   2191   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zP", section);
   2192 
   2193   EXPECT_CALL(handler, Entry(_, 0x0c8350c9, 0xbef11087, 1, "zP", 17))
   2194       .InSequence(s).WillOnce(Return(true));
   2195   EXPECT_CALL(handler, PersonalityRoutine(0xe3eaccac, false))
   2196       .InSequence(s).WillOnce(Return(true));
   2197   EXPECT_CALL(handler, End())
   2198       .InSequence(s).WillOnce(Return(true));
   2199 
   2200   ParseEHFrameSection(&section);
   2201 }
   2202 
   2203 TEST_F(EHFrame, zR) {
   2204   Label cie;
   2205   DwarfPointerEncoding pointer_encoding =
   2206       DwarfPointerEncoding(dwarf2reader::DW_EH_PE_textrel
   2207                            | dwarf2reader::DW_EH_PE_sdata2);
   2208   section.SetPointerEncoding(pointer_encoding);
   2209   section
   2210       .Mark(&cie)
   2211       .CIEHeader(8011, 5496, 75, 1, "zR")
   2212       .ULEB128(1)                       // Augmentation data length
   2213       .D8(pointer_encoding)             // encoding for FDE addresses
   2214       .FinishEntry()
   2215       .FDEHeader(cie, 0x540f9431, 0xbd0)
   2216       .ULEB128(0)                       // Augmentation data length
   2217       .FinishEntry()
   2218       .D32(0);                          // terminator
   2219 
   2220   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zR", section);
   2221 
   2222   EXPECT_CALL(handler, Entry(_, 0x540f9431, 0xbd0, 1, "zR", 75))
   2223       .InSequence(s).WillOnce(Return(true));
   2224   EXPECT_CALL(handler, End())
   2225       .InSequence(s).WillOnce(Return(true));
   2226 
   2227   ParseEHFrameSection(&section);
   2228 }
   2229 
   2230 TEST_F(EHFrame, zS) {
   2231   Label cie;
   2232   section
   2233       .Mark(&cie)
   2234       .CIEHeader(9217, 7694, 57, 1, "zS")
   2235       .ULEB128(0)                                // Augmentation data length
   2236       .FinishEntry()
   2237       .FDEHeader(cie, 0xd40091aa, 0x9aa6e746)
   2238       .ULEB128(0)                                // Augmentation data length
   2239       .FinishEntry()
   2240       .D32(0);                                   // terminator
   2241 
   2242   PERHAPS_WRITE_EH_FRAME_FILE("EHFrame.zS", section);
   2243 
   2244   EXPECT_CALL(handler, Entry(_, 0xd40091aa, 0x9aa6e746, 1, "zS", 57))
   2245       .InSequence(s).WillOnce(Return(true));
   2246   EXPECT_CALL(handler, SignalHandler())
   2247       .InSequence(s).WillOnce(Return(true));
   2248   EXPECT_CALL(handler, End())
   2249       .InSequence(s).WillOnce(Return(true));
   2250 
   2251   ParseEHFrameSection(&section);
   2252 }
   2253 
   2254 // These tests require manual inspection of the test output.
   2255 struct CFIReporterFixture {
   2256   CFIReporterFixture() : reporter("test file name", "test section name") { }
   2257   CallFrameInfo::Reporter reporter;
   2258 };
   2259 
   2260 class CFIReporter: public CFIReporterFixture, public Test { };
   2261 
   2262 TEST_F(CFIReporter, Incomplete) {
   2263   reporter.Incomplete(0x0102030405060708ULL, CallFrameInfo::kUnknown);
   2264 }
   2265 
   2266 TEST_F(CFIReporter, EarlyEHTerminator) {
   2267   reporter.EarlyEHTerminator(0x0102030405060708ULL);
   2268 }
   2269 
   2270 TEST_F(CFIReporter, CIEPointerOutOfRange) {
   2271   reporter.CIEPointerOutOfRange(0x0123456789abcdefULL, 0xfedcba9876543210ULL);
   2272 }
   2273 
   2274 TEST_F(CFIReporter, BadCIEId) {
   2275   reporter.BadCIEId(0x0123456789abcdefULL, 0xfedcba9876543210ULL);
   2276 }
   2277 
   2278 TEST_F(CFIReporter, UnrecognizedVersion) {
   2279   reporter.UnrecognizedVersion(0x0123456789abcdefULL, 43);
   2280 }
   2281 
   2282 TEST_F(CFIReporter, UnrecognizedAugmentation) {
   2283   reporter.UnrecognizedAugmentation(0x0123456789abcdefULL, "poodles");
   2284 }
   2285 
   2286 TEST_F(CFIReporter, InvalidPointerEncoding) {
   2287   reporter.InvalidPointerEncoding(0x0123456789abcdefULL, 0x42);
   2288 }
   2289 
   2290 TEST_F(CFIReporter, UnusablePointerEncoding) {
   2291   reporter.UnusablePointerEncoding(0x0123456789abcdefULL, 0x42);
   2292 }
   2293 
   2294 TEST_F(CFIReporter, RestoreInCIE) {
   2295   reporter.RestoreInCIE(0x0123456789abcdefULL, 0xfedcba9876543210ULL);
   2296 }
   2297 
   2298 TEST_F(CFIReporter, BadInstruction) {
   2299   reporter.BadInstruction(0x0123456789abcdefULL, CallFrameInfo::kFDE,
   2300                           0xfedcba9876543210ULL);
   2301 }
   2302 
   2303 TEST_F(CFIReporter, NoCFARule) {
   2304   reporter.NoCFARule(0x0123456789abcdefULL, CallFrameInfo::kCIE,
   2305                      0xfedcba9876543210ULL);
   2306 }
   2307 
   2308 TEST_F(CFIReporter, EmptyStateStack) {
   2309   reporter.EmptyStateStack(0x0123456789abcdefULL, CallFrameInfo::kTerminator,
   2310                            0xfedcba9876543210ULL);
   2311 }
   2312 
   2313 TEST_F(CFIReporter, ClearingCFARule) {
   2314   reporter.ClearingCFARule(0x0123456789abcdefULL, CallFrameInfo::kFDE,
   2315                            0xfedcba9876543210ULL);
   2316 }
   2317 
   2318 #ifdef WRITE_ELF
   2319 // See comments at the top of the file mentioning WRITE_ELF for details.
   2320 
   2321 using google_breakpad::test_assembler::Section;
   2322 
   2323 struct ELFSectionHeader {
   2324   ELFSectionHeader(unsigned int set_type)
   2325       : type(set_type), flags(0), address(0), link(0), info(0),
   2326         alignment(1), entry_size(0) { }
   2327   Label name;
   2328   unsigned int type;
   2329   uint64_t flags;
   2330   uint64_t address;
   2331   Label file_offset;
   2332   Label file_size;
   2333   unsigned int link;
   2334   unsigned int info;
   2335   uint64_t alignment;
   2336   uint64_t entry_size;
   2337 };
   2338 
   2339 void AppendSectionHeader(CFISection *table, const ELFSectionHeader &header) {
   2340   (*table)
   2341       .D32(header.name)                   // name, index in string tbl
   2342       .D32(header.type)                   // type
   2343       .Address(header.flags)              // flags
   2344       .Address(header.address)            // address in memory
   2345       .Address(header.file_offset)        // offset in ELF file
   2346       .Address(header.file_size)          // length in bytes
   2347       .D32(header.link)                   // link to related section
   2348       .D32(header.info)                   // miscellaneous
   2349       .Address(header.alignment)          // alignment
   2350       .Address(header.entry_size);        // entry size
   2351 }
   2352 
   2353 void WriteELFFrameSection(const char *filename, const char *cfi_name,
   2354                           const CFISection &cfi) {
   2355   int elf_class = cfi.AddressSize() == 4 ? ELFCLASS32 : ELFCLASS64;
   2356   int elf_data = (cfi.endianness() == kBigEndian
   2357                   ? ELFDATA2MSB : ELFDATA2LSB);
   2358   CFISection elf(cfi.endianness(), cfi.AddressSize());
   2359   Label elf_header_size, section_table_offset;
   2360   elf
   2361       .Append("\x7f" "ELF")
   2362       .D8(elf_class)              // 32-bit or 64-bit ELF
   2363       .D8(elf_data)               // endianness
   2364       .D8(1)                      // ELF version
   2365       .D8(ELFOSABI_LINUX)         // Operating System/ABI indication
   2366       .D8(0)                      // ABI version
   2367       .Append(7, 0xda)            // padding
   2368       .D16(ET_EXEC)               // file type: executable file
   2369       .D16(EM_386)                // architecture: Intel IA-32
   2370       .D32(EV_CURRENT);           // ELF version
   2371   elf
   2372       .Address(0x0123456789abcdefULL) // program entry point
   2373       .Address(0)                 // program header offset
   2374       .Address(section_table_offset) // section header offset
   2375       .D32(0)                     // processor-specific flags
   2376       .D16(elf_header_size)       // ELF header size in bytes */
   2377       .D16(elf_class == ELFCLASS32 ? 32 : 56) // program header entry size
   2378       .D16(0)                     // program header table entry count
   2379       .D16(elf_class == ELFCLASS32 ? 40 : 64) // section header entry size
   2380       .D16(3)                     // section  count
   2381       .D16(1)                     // section name string table
   2382       .Mark(&elf_header_size);
   2383 
   2384   // The null section. Every ELF file has one, as the first entry in
   2385   // the section header table.
   2386   ELFSectionHeader null_header(SHT_NULL);
   2387   null_header.file_offset = 0;
   2388   null_header.file_size = 0;
   2389 
   2390   // The CFI section. The whole reason for writing out this ELF file
   2391   // is to put this in it so that we can run other dumping programs on
   2392   // it to check its contents.
   2393   ELFSectionHeader cfi_header(SHT_PROGBITS);
   2394   cfi_header.file_size = cfi.Size();
   2395 
   2396   // The section holding the names of the sections. This is the
   2397   // section whose index appears in the e_shstrndx member of the ELF
   2398   // header.
   2399   ELFSectionHeader section_names_header(SHT_STRTAB);
   2400   CFISection section_names(cfi.endianness(), cfi.AddressSize());
   2401   section_names
   2402       .Mark(&null_header.name)
   2403       .AppendCString("")
   2404       .Mark(&section_names_header.name)
   2405       .AppendCString(".shstrtab")
   2406       .Mark(&cfi_header.name)
   2407       .AppendCString(cfi_name)
   2408       .Mark(&section_names_header.file_size);
   2409 
   2410   // Create the section table. The ELF header's e_shoff member refers
   2411   // to this, and the e_shnum member gives the number of entries it
   2412   // contains.
   2413   CFISection section_table(cfi.endianness(), cfi.AddressSize());
   2414   AppendSectionHeader(&section_table, null_header);
   2415   AppendSectionHeader(&section_table, section_names_header);
   2416   AppendSectionHeader(&section_table, cfi_header);
   2417 
   2418   // Append the section table and the section contents to the ELF file.
   2419   elf
   2420       .Mark(&section_table_offset)
   2421       .Append(section_table)
   2422       .Mark(&section_names_header.file_offset)
   2423       .Append(section_names)
   2424       .Mark(&cfi_header.file_offset)
   2425       .Append(cfi);
   2426 
   2427   string contents;
   2428   if (!elf.GetContents(&contents)) {
   2429     fprintf(stderr, "failed to get ELF file contents\n");
   2430     exit(1);
   2431   }
   2432 
   2433   FILE *out = fopen(filename, "w");
   2434   if (!out) {
   2435     fprintf(stderr, "error opening ELF file '%s': %s\n",
   2436             filename, strerror(errno));
   2437     exit(1);
   2438   }
   2439 
   2440   if (fwrite(contents.data(), 1, contents.size(), out) != contents.size()) {
   2441     fprintf(stderr, "error writing ELF data to '%s': %s\n",
   2442             filename, strerror(errno));
   2443     exit(1);
   2444   }
   2445 
   2446   if (fclose(out) == EOF) {
   2447     fprintf(stderr, "error closing ELF file '%s': %s\n",
   2448             filename, strerror(errno));
   2449     exit(1);
   2450   }
   2451 }
   2452 #endif
   2453