// -*- mode: c++ -*-

// Copyright (c) 2010 Google Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>

// dwarf2diehander_unittest.cc: Unit tests for google_breakpad::DIEDispatcher.

#include <stdint.h>

#include <string>
#include <utility>

#include "breakpad_googletest_includes.h"

#include "common/dwarf/dwarf2diehandler.h"
#include "common/using_std_string.h"

using std::make_pair;

using ::testing::_;
using ::testing::ContainerEq;
using ::testing::ElementsAreArray;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::StrEq;

using dwarf2reader::DIEDispatcher;
using dwarf2reader::DIEHandler;
using dwarf2reader::DwarfAttribute;
using dwarf2reader::DwarfForm;
using dwarf2reader::DwarfTag;
using dwarf2reader::RootDIEHandler;

class MockDIEHandler: public DIEHandler {
 public:
  MOCK_METHOD3(ProcessAttributeUnsigned,
               void(DwarfAttribute, DwarfForm, uint64_t));
  MOCK_METHOD3(ProcessAttributeSigned,
               void(DwarfAttribute, DwarfForm, int64_t));
  MOCK_METHOD3(ProcessAttributeReference,
               void(DwarfAttribute, DwarfForm, uint64_t));
  MOCK_METHOD4(ProcessAttributeBuffer,
               void(DwarfAttribute, DwarfForm, const uint8_t*, uint64_t));
  MOCK_METHOD3(ProcessAttributeString,
               void(DwarfAttribute, DwarfForm, const string&));
  MOCK_METHOD3(ProcessAttributeSignature,
               void(DwarfAttribute, DwarfForm, uint64_t));
  MOCK_METHOD0(EndAttributes, bool());
  MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64_t, DwarfTag));
  MOCK_METHOD0(Finish, void());
};

class MockRootDIEHandler: public RootDIEHandler {
 public:
  MOCK_METHOD3(ProcessAttributeUnsigned,
               void(DwarfAttribute, DwarfForm, uint64_t));
  MOCK_METHOD3(ProcessAttributeSigned,
               void(DwarfAttribute, DwarfForm, int64_t));
  MOCK_METHOD3(ProcessAttributeReference,
               void(DwarfAttribute, DwarfForm, uint64_t));
  MOCK_METHOD4(ProcessAttributeBuffer,
               void(DwarfAttribute, DwarfForm, const uint8_t*, uint64_t));
  MOCK_METHOD3(ProcessAttributeString,
               void(DwarfAttribute, DwarfForm, const string&));
  MOCK_METHOD3(ProcessAttributeSignature,
               void(DwarfAttribute, DwarfForm, uint64_t));
  MOCK_METHOD0(EndAttributes, bool());
  MOCK_METHOD2(FindChildHandler, DIEHandler *(uint64_t, DwarfTag));
  MOCK_METHOD0(Finish, void());
  MOCK_METHOD5(StartCompilationUnit, bool(uint64_t, uint8_t, uint8_t, uint64_t,
                                          uint8_t));
  MOCK_METHOD2(StartRootDIE, bool(uint64_t, DwarfTag));
};

// If the handler elects to skip the compilation unit, the dispatcher
// should tell the reader so.
TEST(Dwarf2DIEHandler, SkipCompilationUnit) {
  Sequence s;
  MockRootDIEHandler mock_root_handler;
  DIEDispatcher die_dispatcher(&mock_root_handler);

  EXPECT_CALL(mock_root_handler,
              StartCompilationUnit(0x8d42aed77cfccf3eLL,
                                   0x89, 0xdc,
                                   0x2ecb4dc778a80f21LL,
                                   0x66))
      .InSequence(s)
      .WillOnce(Return(false));

  EXPECT_FALSE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL,
                                                   0x89, 0xdc,
                                                   0x2ecb4dc778a80f21LL,
                                                   0x66));
}

// If the handler elects to skip the root DIE, the dispatcher should
// tell the reader so.
TEST(Dwarf2DIEHandler, SkipRootDIE) {
  Sequence s;
  MockRootDIEHandler mock_root_handler;
  DIEDispatcher die_dispatcher(&mock_root_handler);

  EXPECT_CALL(mock_root_handler,
              StartCompilationUnit(0xde8994029fc8b999LL, 0xf4, 0x02,
                                   0xb00febffa76e2b2bLL, 0x5c))
      .InSequence(s)
      .WillOnce(Return(true));
  EXPECT_CALL(mock_root_handler,
              StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6))
      .InSequence(s)
      .WillOnce(Return(false));

  EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0xde8994029fc8b999LL, 
                                                  0xf4, 0x02,
                                                  0xb00febffa76e2b2bLL, 0x5c));
  EXPECT_FALSE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL,
                                       (DwarfTag) 0xb4f98da6));
  die_dispatcher.EndDIE(0x7d08242b4b510cf2LL);
}

// If the handler elects to skip the root DIE's children, the
// dispatcher should tell the reader so --- and avoid deleting the
// root handler.
TEST(Dwarf2DIEHandler, SkipRootDIEChildren) {
  MockRootDIEHandler mock_root_handler;
  DIEDispatcher die_dispatcher(&mock_root_handler);

  {
    InSequence s;

    EXPECT_CALL(mock_root_handler,
                StartCompilationUnit(0x15d6897480cc65a7LL, 0x26, 0xa0,
                                     0x09f8bf0767f91675LL, 0xdb))
      .WillOnce(Return(true));
    EXPECT_CALL(mock_root_handler,
                StartRootDIE(0x7d08242b4b510cf2LL, (DwarfTag) 0xb4f98da6))
      .WillOnce(Return(true));
    // Please don't tell me about my children.
    EXPECT_CALL(mock_root_handler, EndAttributes())
      .WillOnce(Return(false));
    EXPECT_CALL(mock_root_handler, Finish())
      .WillOnce(Return());
  }

  EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x15d6897480cc65a7LL,
                                                  0x26, 0xa0,
                                                  0x09f8bf0767f91675LL, 0xdb));
  EXPECT_TRUE(die_dispatcher.StartDIE(0x7d08242b4b510cf2LL,
                                      (DwarfTag) 0xb4f98da6));
  EXPECT_FALSE(die_dispatcher.StartDIE(0x435150ceedccda18LL,
                                       (DwarfTag) 0xc3a17bba));
  die_dispatcher.EndDIE(0x435150ceedccda18LL);
  die_dispatcher.EndDIE(0x7d08242b4b510cf2LL);
}

// The dispatcher should pass attribute values through to the die
// handler accurately.
TEST(Dwarf2DIEHandler, PassAttributeValues) {
  MockRootDIEHandler mock_root_handler;
  DIEDispatcher die_dispatcher(&mock_root_handler);

  const uint8_t buffer[10] = {
    0x24, 0x24, 0x35, 0x9a, 0xca, 0xcf, 0xa8, 0x84, 0xa7, 0x18
  };
  string str = "\xc8\x26\x2e\x0d\xa4\x9c\x37\xd6\xfb\x1d";

  // Set expectations.
  {
    InSequence s;

    // We'll like the compilation unit header.
    EXPECT_CALL(mock_root_handler,
                StartCompilationUnit(0x8d42aed77cfccf3eLL, 0x89, 0xdc,
                                     0x2ecb4dc778a80f21LL, 0x66))
      .WillOnce(Return(true));

    // We'll like the root DIE.
    EXPECT_CALL(mock_root_handler,
                StartRootDIE(0xe2222da01e29f2a9LL, (DwarfTag) 0x9829445c))
      .WillOnce(Return(true));

    // Expect some attribute values.
    EXPECT_CALL(mock_root_handler,
                ProcessAttributeUnsigned((DwarfAttribute) 0x1cc0bfed,
                                         (DwarfForm) 0x424f1468,
                                         0xa592571997facda1ULL))
      .WillOnce(Return());
    EXPECT_CALL(mock_root_handler,
                ProcessAttributeSigned((DwarfAttribute) 0x43694dc9,
                                       (DwarfForm) 0xf6f78901L,
                                       0x92602a4e3bf1f446LL))
      .WillOnce(Return());
    EXPECT_CALL(mock_root_handler,
                ProcessAttributeReference((DwarfAttribute) 0x4033e8cL,
                                          (DwarfForm) 0xf66fbe0bL,
                                          0x50fddef44734fdecULL))
      .WillOnce(Return());
    EXPECT_CALL(mock_root_handler,
                ProcessAttributeBuffer((DwarfAttribute) 0x25d7e0af,
                                       (DwarfForm) 0xe99a539a,
                                       buffer, sizeof(buffer)))
      .WillOnce(Return());
    EXPECT_CALL(mock_root_handler,
                ProcessAttributeString((DwarfAttribute) 0x310ed065,
                                       (DwarfForm) 0x15762fec,
                                       StrEq(str)))
      .WillOnce(Return());
    EXPECT_CALL(mock_root_handler,
                ProcessAttributeSignature((DwarfAttribute) 0x58790d72,
                                          (DwarfForm) 0x4159f138,
                                          0x94682463613e6a5fULL))
      .WillOnce(Return());
    EXPECT_CALL(mock_root_handler, EndAttributes())
      .WillOnce(Return(true));
    EXPECT_CALL(mock_root_handler, FindChildHandler(_, _))
      .Times(0);
    EXPECT_CALL(mock_root_handler, Finish())
      .WillOnce(Return());
  }

  // Drive the dispatcher.

  // Report the CU header.
  EXPECT_TRUE(die_dispatcher.StartCompilationUnit(0x8d42aed77cfccf3eLL,
                                                  0x89, 0xdc,
                                                  0x2ecb4dc778a80f21LL,
                                                  0x66));
  // Report the root DIE.
  EXPECT_TRUE(die_dispatcher.StartDIE(0xe2222da01e29f2a9LL,
                                      (DwarfTag) 0x9829445c));

  // Report some attribute values.
  die_dispatcher.ProcessAttributeUnsigned(0xe2222da01e29f2a9LL,
                                          (DwarfAttribute) 0x1cc0bfed,
                                          (DwarfForm) 0x424f1468,
                                          0xa592571997facda1ULL);
  die_dispatcher.ProcessAttributeSigned(0xe2222da01e29f2a9LL,
                                        (DwarfAttribute) 0x43694dc9,
                                        (DwarfForm) 0xf6f78901,
                                        0x92602a4e3bf1f446LL);
  die_dispatcher.ProcessAttributeReference(0xe2222da01e29f2a9LL,
                                           (DwarfAttribute) 0x4033e8c,
                                           (DwarfForm) 0xf66fbe0b,
                                           0x50fddef44734fdecULL);
  die_dispatcher.ProcessAttributeBuffer(0xe2222da01e29f2a9LL,
                                        (DwarfAttribute) 0x25d7e0af,
                                        (DwarfForm) 0xe99a539a,
                                        buffer, sizeof(buffer));
  die_dispatcher.ProcessAttributeString(0xe2222da01e29f2a9LL,
                                        (DwarfAttribute) 0x310ed065,
                                        (DwarfForm) 0x15762fec,
                                        str);
  die_dispatcher.ProcessAttributeSignature(0xe2222da01e29f2a9LL,
                                           (DwarfAttribute) 0x58790d72,
                                           (DwarfForm) 0x4159f138,
                                           0x94682463613e6a5fULL);

  // Finish the root DIE (and thus the CU).
  die_dispatcher.EndDIE(0xe2222da01e29f2a9LL);
}

TEST(Dwarf2DIEHandler, FindAndSkipChildren) {
  MockRootDIEHandler mock_root_handler;
  MockDIEHandler *mock_child1_handler = new(MockDIEHandler);
  MockDIEHandler *mock_child3_handler = new(MockDIEHandler);
  DIEDispatcher die_dispatcher(&mock_root_handler);

  {
    InSequence s;

    // We'll like the compilation unit header.
    EXPECT_CALL(mock_root_handler,
                StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21,
                                     0x47dd3c764275a216LL, 0xa5))
      .WillOnce(Return(true));

    // Root DIE.
    {
      EXPECT_CALL(mock_root_handler,
                  StartRootDIE(0x15f0e06bdfe3c372LL, (DwarfTag) 0xf5d60c59))
        .WillOnce(Return(true));
      EXPECT_CALL(mock_root_handler,
                  ProcessAttributeSigned((DwarfAttribute) 0xf779a642,
                                         (DwarfForm) 0x2cb63027,
                                         0x18e744661769d08fLL))
        .WillOnce(Return());
      EXPECT_CALL(mock_root_handler, EndAttributes())
        .WillOnce(Return(true));

      // First child DIE.
      EXPECT_CALL(mock_root_handler,
                  FindChildHandler(0x149f644f8116fe8cLL,
                                   (DwarfTag) 0xac2cbd8c))
        .WillOnce(Return(mock_child1_handler));
      {
        EXPECT_CALL(*mock_child1_handler,
                    ProcessAttributeSigned((DwarfAttribute) 0xa6fd6f65,
                                           (DwarfForm) 0xe4f64c41,
                                           0x1b04e5444a55fe67LL))
          .WillOnce(Return());
        EXPECT_CALL(*mock_child1_handler, EndAttributes())
          .WillOnce(Return(false));
        // Skip first grandchild DIE and first great-grandchild DIE.
        EXPECT_CALL(*mock_child1_handler, Finish())
          .WillOnce(Return());
      }

      // Second child DIE.  Root handler will decline to return a handler
      // for this child.
      EXPECT_CALL(mock_root_handler,
                  FindChildHandler(0x97412be24875de9dLL,
                                   (DwarfTag) 0x505a068b))
        .WillOnce(Return((DIEHandler*) NULL));

      // Third child DIE.
      EXPECT_CALL(mock_root_handler,
                  FindChildHandler(0x753c964c8ab538aeLL,
                                   (DwarfTag) 0x8c22970e))
        .WillOnce(Return(mock_child3_handler));
      {
        EXPECT_CALL(*mock_child3_handler,
                    ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb,
                                           (DwarfForm) 0x610b7ae1,
                                           0x3ea5c609d7d7560fLL))
          .WillOnce(Return());
        EXPECT_CALL(*mock_child3_handler, EndAttributes())
          .WillOnce(Return(true));
        EXPECT_CALL(*mock_child3_handler, Finish())
          .WillOnce(Return());
      }

      EXPECT_CALL(mock_root_handler, Finish())
        .WillOnce(Return());
    }
  }

    
  // Drive the dispatcher.

  // Report the CU header.
  EXPECT_TRUE(die_dispatcher
              .StartCompilationUnit(0x9ec1e6d05e434a0eLL, 0xeb, 0x21,
                                    0x47dd3c764275a216LL, 0xa5));
  // Report the root DIE.
  {
    EXPECT_TRUE(die_dispatcher.StartDIE(0x15f0e06bdfe3c372LL,
                                        (DwarfTag) 0xf5d60c59));
    die_dispatcher.ProcessAttributeSigned(0x15f0e06bdfe3c372LL,
                                          (DwarfAttribute) 0xf779a642,
                                          (DwarfForm) 0x2cb63027,
                                          0x18e744661769d08fLL);

    // First child DIE.
    {
      EXPECT_TRUE(die_dispatcher.StartDIE(0x149f644f8116fe8cLL,
                                          (DwarfTag) 0xac2cbd8c));
      die_dispatcher.ProcessAttributeSigned(0x149f644f8116fe8cLL,
                                            (DwarfAttribute) 0xa6fd6f65,
                                            (DwarfForm) 0xe4f64c41,
                                            0x1b04e5444a55fe67LL);

      // First grandchild DIE.  Will be skipped.
      {
        EXPECT_FALSE(die_dispatcher.StartDIE(0xd68de1ee0bd29419LL,
                                            (DwarfTag) 0x22f05a15));
        // First great-grandchild DIE.  Will be skipped without being
        // mentioned to any handler.
        {
          EXPECT_FALSE(die_dispatcher
                       .StartDIE(0xb3076285d25cac25LL,
                                 (DwarfTag) 0xcff4061b));
          die_dispatcher.EndDIE(0xb3076285d25cac25LL);          
        }
        die_dispatcher.EndDIE(0xd68de1ee0bd29419LL);
      }
      die_dispatcher.EndDIE(0x149f644f8116fe8cLL);
    }

    // Second child DIE.  Root handler will decline to find a handler for it.
    {
      EXPECT_FALSE(die_dispatcher.StartDIE(0x97412be24875de9dLL,
                                           (DwarfTag) 0x505a068b));
      die_dispatcher.EndDIE(0x97412be24875de9dLL);
    }
    
    // Third child DIE.
    {
      EXPECT_TRUE(die_dispatcher.StartDIE(0x753c964c8ab538aeLL,
                                          (DwarfTag) 0x8c22970e));
      die_dispatcher.ProcessAttributeSigned(0x753c964c8ab538aeLL,
                                            (DwarfAttribute) 0x4e2b7cfb,
                                            (DwarfForm) 0x610b7ae1,
                                            0x3ea5c609d7d7560fLL);
      die_dispatcher.EndDIE(0x753c964c8ab538aeLL);
    }
    
    // Finish the root DIE (and thus the CU).
    die_dispatcher.EndDIE(0x15f0e06bdfe3c372LL);
  }
}

// The DIEDispatcher destructor is supposed to delete all handlers on
// the stack, except for the root.
TEST(Dwarf2DIEHandler, FreeHandlersOnStack) {
  MockRootDIEHandler mock_root_handler;
  MockDIEHandler *mock_child_handler = new(MockDIEHandler);
  MockDIEHandler *mock_grandchild_handler = new(MockDIEHandler);

  {
    InSequence s;

    // We'll like the compilation unit header.
    EXPECT_CALL(mock_root_handler,
                StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89,
                                     0x76d392ff393ddda2LL, 0xbf))
      .WillOnce(Return(true));

    // Root DIE.
    {
      EXPECT_CALL(mock_root_handler,
                  StartRootDIE(0xbf13b761691ddc91LL, (DwarfTag) 0x98980361))
        .WillOnce(Return(true));
      EXPECT_CALL(mock_root_handler, EndAttributes())
        .WillOnce(Return(true));
      
      // Child DIE.
      EXPECT_CALL(mock_root_handler,
                  FindChildHandler(0x058f09240c5fc8c9LL,
                                   (DwarfTag) 0x898bf0d0))
        .WillOnce(Return(mock_child_handler));
      {
        EXPECT_CALL(*mock_child_handler, EndAttributes())
          .WillOnce(Return(true));

        // Grandchild DIE.
        EXPECT_CALL(*mock_child_handler,
                    FindChildHandler(0x32dc00c9945dc0c8LL,
                                     (DwarfTag) 0x2802d007))
          .WillOnce(Return(mock_grandchild_handler));
        {
          EXPECT_CALL(*mock_grandchild_handler,
                      ProcessAttributeSigned((DwarfAttribute) 0x4e2b7cfb,
                                             (DwarfForm) 0x610b7ae1,
                                             0x3ea5c609d7d7560fLL))
            .WillOnce(Return());

          // At this point, we abandon the traversal, so none of the
          // usual stuff should get called.
          EXPECT_CALL(*mock_grandchild_handler, EndAttributes())
            .Times(0);
          EXPECT_CALL(*mock_grandchild_handler, Finish())
            .Times(0);
        }

        EXPECT_CALL(*mock_child_handler, Finish())
          .Times(0);
      }

      EXPECT_CALL(mock_root_handler, Finish())
        .Times(0);
    }
  }

  // The dispatcher.
  DIEDispatcher die_dispatcher(&mock_root_handler);
  
  // Report the CU header.
  EXPECT_TRUE(die_dispatcher
              .StartCompilationUnit(0x87b41ba8381cd71cLL, 0xff, 0x89,
                                    0x76d392ff393ddda2LL, 0xbf));
  // Report the root DIE.
  {
    EXPECT_TRUE(die_dispatcher.StartDIE(0xbf13b761691ddc91LL,
                                        (DwarfTag) 0x98980361));

    // Child DIE.
    {
      EXPECT_TRUE(die_dispatcher.StartDIE(0x058f09240c5fc8c9LL,
                                          (DwarfTag) 0x898bf0d0));

      // Grandchild DIE.
      {
        EXPECT_TRUE(die_dispatcher.StartDIE(0x32dc00c9945dc0c8LL,
                                            (DwarfTag) 0x2802d007));
        die_dispatcher.ProcessAttributeSigned(0x32dc00c9945dc0c8LL,
                                              (DwarfAttribute) 0x4e2b7cfb,
                                              (DwarfForm) 0x610b7ae1,
                                              0x3ea5c609d7d7560fLL);

        // Stop the traversal abruptly, so that there will still be
        // handlers on the stack when the dispatcher is destructed.

        // No EndDIE call...
      }
      // No EndDIE call...
    }
    // No EndDIE call...
  }
}
