toolkit/crashreporter/google-breakpad/src/common/stabs_reader_unittest.cc

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

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

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

     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.
    30 // Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
    32 // stabs_reader_unittest.cc: Unit tests for google_breakpad::StabsReader.
    34 #include <assert.h>
    35 #include <errno.h>
    36 #include <stab.h>
    37 #include <stdarg.h>
    38 #include <stdlib.h>
    39 #include <string.h>
    41 #include <fstream>
    42 #include <iomanip>
    43 #include <iostream>
    44 #include <map>
    45 #include <sstream>
    46 #include <string>
    48 #include "breakpad_googletest_includes.h"
    49 #include "common/stabs_reader.h"
    50 #include "common/test_assembler.h"
    51 #include "common/using_std_string.h"
    53 using ::testing::Eq;
    54 using ::testing::InSequence;
    55 using ::testing::Return;
    56 using ::testing::StrEq;
    57 using ::testing::Test;
    58 using ::testing::_;
    59 using google_breakpad::StabsHandler;
    60 using google_breakpad::StabsReader;
    61 using google_breakpad::test_assembler::Label;
    62 using google_breakpad::test_assembler::Section;
    63 using google_breakpad::test_assembler::kBigEndian;
    64 using google_breakpad::test_assembler::kLittleEndian;
    65 using std::map;
    67 namespace {
    69 // A StringAssembler is a class for generating .stabstr sections to present
    70 // as input to the STABS parser.
    71 class StringAssembler: public Section {
    72  public:
    73   StringAssembler() : in_cu_(false) { StartCU(); }
    75   // Add the string S to this StringAssembler, and return the string's
    76   // offset within this compilation unit's strings. If S has been added
    77   // already, this returns the offset of its first instance.
    78   size_t Add(const string &s) {
    79     map<string, size_t>::iterator it = added_.find(s);
    80     if (it != added_.end())
    81       return it->second;
    82     size_t offset = Size() - cu_start_;
    83     AppendCString(s);
    84     added_[s] = offset;
    85     return offset;
    86   }
    88   // Start a fresh compilation unit string collection.
    89   void StartCU() {
    90     // Ignore duplicate calls to StartCU. Our test data don't always call
    91     // StartCU at all, meaning that our constructor has to take care of it,
    92     // meaning that tests that *do* call StartCU call it twice at the
    93     // beginning.  This is not worth smoothing out.
    94     if (in_cu_) return;
    96     added_.clear();
    97     cu_start_ = Size();
    99     // Each compilation unit's strings start with an empty string.
   100     AppendCString("");
   101     added_[""] = 0;
   103     in_cu_ = true;
   104   }
   106   // Finish off the current CU's strings.
   107   size_t EndCU() {
   108     assert(in_cu_);
   109     in_cu_ = false;
   110     return Size() - cu_start_;
   111   }
   113  private:
   114   // The offset of the start of this compilation unit's strings.
   115   size_t cu_start_;
   117   // True if we're in a CU.
   118   bool in_cu_;
   120   // A map from the strings that have been added to this section to
   121   // their starting indices within their compilation unit.
   122   map<string, size_t> added_;
   123 };
   125 // A StabsAssembler is a class for generating .stab sections to present as
   126 // test input for the STABS parser.
   127 class StabsAssembler: public Section {
   128  public:
   129   // Create a StabsAssembler that uses StringAssembler for its strings.
   130   StabsAssembler(StringAssembler *string_assembler)
   131       : Section(string_assembler->endianness()),
   132         string_assembler_(string_assembler),
   133         value_size_(0),
   134         entry_count_(0),
   135         cu_header_(NULL) { }
   136   ~StabsAssembler() { assert(!cu_header_); }
   138   // Accessor and setter for value_size_.
   139   size_t value_size() const { return value_size_; }
   140   StabsAssembler &set_value_size(size_t value_size) {
   141     value_size_ = value_size;
   142     return *this;
   143   }
   145   // Append a STAB entry to the end of this section with the given
   146   // characteristics. NAME is the offset of this entry's name string within
   147   // its compilation unit's portion of the .stabstr section; this can be a
   148   // value generated by a StringAssembler. Return a reference to this
   149   // StabsAssembler.
   150   StabsAssembler &Stab(uint8_t type, uint8_t other, Label descriptor,
   151                        Label value, Label name) {
   152     D32(name);
   153     D8(type);
   154     D8(other);
   155     D16(descriptor);
   156     Append(endianness(), value_size_, value);
   157     entry_count_++;
   158     return *this;
   159   }
   161   // As above, but automatically add NAME to our StringAssembler.
   162   StabsAssembler &Stab(uint8_t type, uint8_t other, Label descriptor,
   163                        Label value, const string &name) {
   164     return Stab(type, other, descriptor, value, string_assembler_->Add(name));
   165   }
   167   // Start a compilation unit named NAME, with an N_UNDF symbol to start
   168   // it, and its own portion of the string section. Return a reference to
   169   // this StabsAssembler.
   170   StabsAssembler &StartCU(const string &name) {
   171     assert(!cu_header_);
   172     cu_header_ = new CUHeader;
   173     string_assembler_->StartCU();
   174     entry_count_ = 0;
   175     return Stab(N_UNDF, 0,
   176                 cu_header_->final_entry_count,
   177                 cu_header_->final_string_size,
   178                 string_assembler_->Add(name));
   179   }
   181   // Close off the current compilation unit. Return a reference to this
   182   // StabsAssembler.
   183   StabsAssembler &EndCU() {
   184     assert(cu_header_);
   185     cu_header_->final_entry_count = entry_count_;
   186     cu_header_->final_string_size = string_assembler_->EndCU();
   187     delete cu_header_;
   188     cu_header_ = NULL;
   189     return *this;
   190   }
   192  private:
   193   // Data used in a compilation unit header STAB that we won't know until
   194   // we've finished the compilation unit.
   195   struct CUHeader {
   196     // The final number of entries this compilation unit will hold.
   197     Label final_entry_count;
   199     // The final size of this compilation unit's strings.
   200     Label final_string_size;
   201   };
   203   // The strings for our STABS entries.
   204   StringAssembler *string_assembler_;
   206   // The size of the 'value' field of stabs entries in this section.
   207   size_t value_size_;
   209   // The number of entries in this compilation unit so far.
   210   size_t entry_count_;
   212   // Header labels for this compilation unit, if we've started one but not
   213   // finished it.
   214   CUHeader *cu_header_;
   215 };
   217 class MockStabsReaderHandler: public StabsHandler {
   218  public:
   219   MOCK_METHOD3(StartCompilationUnit,
   220                bool(const char *, uint64_t, const char *));
   221   MOCK_METHOD1(EndCompilationUnit, bool(uint64_t));
   222   MOCK_METHOD2(StartFunction, bool(const string &, uint64_t));
   223   MOCK_METHOD1(EndFunction, bool(uint64_t));
   224   MOCK_METHOD3(Line, bool(uint64_t, const char *, int));
   225   MOCK_METHOD2(Extern, bool(const string &, uint64_t));
   226   void Warning(const char *format, ...) { MockWarning(format); }
   227   MOCK_METHOD1(MockWarning, void(const char *));
   228 };
   230 struct StabsFixture {
   231   StabsFixture() : stabs(&strings), unitized(true) { }
   233   // Create a StabsReader to parse the mock stabs data in stabs and
   234   // strings, and pass the parsed information to mock_handler. Use the
   235   // endianness and value size of stabs to parse the data. If all goes
   236   // well, return the result of calling the reader's Process member
   237   // function. Otherwise, return false.
   238   bool ApplyHandlerToMockStabsData() {
   239     string stabs_contents, stabstr_contents;
   240     if (!stabs.GetContents(&stabs_contents) ||
   241         !strings.GetContents(&stabstr_contents))
   242       return false;
   244     // Run the parser on the test input, passing whatever we find to HANDLER.
   245     StabsReader reader(
   246         reinterpret_cast<const uint8_t *>(stabs_contents.data()),
   247         stabs_contents.size(),
   248         reinterpret_cast<const uint8_t *>(stabstr_contents.data()),
   249         stabstr_contents.size(),
   250         stabs.endianness() == kBigEndian, stabs.value_size(), unitized,
   251         &mock_handler);
   252     return reader.Process();
   253   }
   255   StringAssembler strings;
   256   StabsAssembler stabs;
   257   bool unitized;
   258   MockStabsReaderHandler mock_handler;
   259 };
   261 class Stabs: public StabsFixture, public Test { };
   263 TEST_F(Stabs, MockStabsInput) {
   264   stabs.set_endianness(kLittleEndian);
   265   stabs.set_value_size(4);
   266   stabs
   267       .Stab(N_SO,      149, 40232, 0x18a2a72bU, "builddir/")
   268       .Stab(N_FUN,      83, 50010, 0x91a5353fU,
   269             "not the SO with source file name we expected ")
   270       .Stab(N_SO,      165, 24791, 0xfe69d23cU, "")
   271       .Stab(N_SO,      184, 34178, 0xca4d883aU, "builddir1/")
   272       .Stab(N_SO,       83, 40859, 0xd2fe5df3U, "file1.c")
   273       .Stab(N_LSYM,    147, 39565, 0x60d4bb8aU, "not the FUN we're looking for")
   274       .Stab(N_FUN,     120, 50271, 0xa049f4b1U, "fun1")
   275       .Stab(N_BINCL,   150, 15694, 0xef65c659U,
   276             "something to ignore in a FUN body")
   277       .Stab(N_SLINE,   147,  4967, 0xd904b3f, "")
   278       .Stab(N_SOL,     177, 56135, 0xbd97b1dcU, "header.h")
   279       .Stab(N_SLINE,   130, 24610, 0x90f145b, "")
   280       .Stab(N_FUN,      45, 32441, 0xbf27cf93U,
   281             "fun2:some stabs type info here:to trim from the name")
   282       .Stab(N_SLINE,   138, 39002, 0x8148b87, "")
   283       .Stab(N_SOL,      60, 49318, 0x1d06e025U, "file1.c")
   284       .Stab(N_SLINE,    29, 52163, 0x6eebbb7, "")
   285       .Stab(N_SO,      167,  4647, 0xd04b7448U, "")
   286       .Stab(N_LSYM,     58, 37837, 0xe6b14d37U, "")
   287       .Stab(N_SO,      152,  7810, 0x11759f10U, "file3.c")
   288       .Stab(N_SO,      218, 12447, 0x11cfe4b5U, "");
   290   {
   291     InSequence s;
   293     EXPECT_CALL(mock_handler,
   294                 StartCompilationUnit(StrEq("file1.c"), 0xd2fe5df3U,
   295                                      StrEq("builddir1/")))
   296         .WillOnce(Return(true));
   297     EXPECT_CALL(mock_handler, StartFunction(StrEq("fun1"), 0xa049f4b1U))
   298         .WillOnce(Return(true));
   299     EXPECT_CALL(mock_handler,
   300                 Line(0xa049f4b1U + 0xd904b3f, StrEq("file1.c"), 4967))
   301         .WillOnce(Return(true));
   302     EXPECT_CALL(mock_handler,
   303                 Line(0xa049f4b1U + 0x90f145b, StrEq("header.h"), 24610))
   304         .WillOnce(Return(true));
   305     EXPECT_CALL(mock_handler, EndFunction(0xbf27cf93U))
   306         .WillOnce(Return(true));
   307     EXPECT_CALL(mock_handler, StartFunction(StrEq("fun2"), 0xbf27cf93U))
   308         .WillOnce(Return(true));
   309     EXPECT_CALL(mock_handler,
   310                 Line(0xbf27cf93U + 0x8148b87, StrEq("header.h"), 39002))
   311         .WillOnce(Return(true));
   312     EXPECT_CALL(mock_handler,
   313                 Line(0xbf27cf93U + 0x6eebbb7, StrEq("file1.c"), 52163))
   314         .WillOnce(Return(true));
   315     EXPECT_CALL(mock_handler, EndFunction(0xd04b7448U))
   316         .WillOnce(Return(true));
   317     EXPECT_CALL(mock_handler, EndCompilationUnit(0xd04b7448U))
   318         .WillOnce(Return(true));
   319     EXPECT_CALL(mock_handler, StartCompilationUnit(StrEq("file3.c"),
   320                                                    0x11759f10U, NULL))
   321         .WillOnce(Return(true));
   322     EXPECT_CALL(mock_handler, EndCompilationUnit(0x11cfe4b5U))
   323         .WillOnce(Return(true));
   324   }
   326   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   327 }
   329 TEST_F(Stabs, AbruptCU) {
   330   stabs.set_endianness(kBigEndian);
   331   stabs.set_value_size(4);
   332   stabs.Stab(N_SO, 177, 23446, 0xbf10d5e4, "file2-1.c");
   334   {
   335     InSequence s;
   337     EXPECT_CALL(mock_handler,
   338                 StartCompilationUnit(StrEq("file2-1.c"), 0xbf10d5e4, NULL))
   339         .WillOnce(Return(true));
   340     EXPECT_CALL(mock_handler, EndCompilationUnit(0))
   341         .WillOnce(Return(true));
   342   }
   344   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   345 }
   347 TEST_F(Stabs, AbruptFunction) {
   348   stabs.set_endianness(kLittleEndian);
   349   stabs.set_value_size(8);
   350   stabs
   351       .Stab(N_SO,      218,   26631,   0xb83ddf10U, "file3-1.c")
   352       .Stab(N_FUN,     113,   24765,   0xbbd4a145U, "fun3_1");
   354   {
   355     InSequence s;
   357     EXPECT_CALL(mock_handler,
   358                 StartCompilationUnit(StrEq("file3-1.c"), 0xb83ddf10U, NULL))
   359         .WillOnce(Return(true));
   360     EXPECT_CALL(mock_handler, StartFunction(StrEq("fun3_1"), 0xbbd4a145U))
   361         .WillOnce(Return(true));
   362     EXPECT_CALL(mock_handler, EndFunction(0))
   363         .WillOnce(Return(true));
   364     EXPECT_CALL(mock_handler, EndCompilationUnit(0))
   365         .WillOnce(Return(true));
   366   }
   368   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   369 }
   371 TEST_F(Stabs, NoCU) {
   372   stabs.set_endianness(kBigEndian);
   373   stabs.set_value_size(8);
   374   stabs.Stab(N_SO, 161, 25673, 0x8f676e7bU, "build-directory/");
   376   EXPECT_CALL(mock_handler, StartCompilationUnit(_, _, _))
   377       .Times(0);
   378   EXPECT_CALL(mock_handler, StartFunction(_, _))
   379       .Times(0);
   381   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   382 }
   384 TEST_F(Stabs, NoCUEnd) {
   385   stabs.set_endianness(kBigEndian);
   386   stabs.set_value_size(8);
   387   stabs
   388       .Stab(N_SO,      116,   58280,   0x2f7493c9U, "file5-1.c")
   389       .Stab(N_SO,      224,   23057,   0xf9f1d50fU, "file5-2.c");
   391   {
   392     InSequence s;
   394     EXPECT_CALL(mock_handler,
   395                 StartCompilationUnit(StrEq("file5-1.c"), 0x2f7493c9U, NULL))
   396         .WillOnce(Return(true));
   397     EXPECT_CALL(mock_handler, EndCompilationUnit(0))
   398         .WillOnce(Return(true));
   399     EXPECT_CALL(mock_handler,
   400                 StartCompilationUnit(StrEq("file5-2.c"), 0xf9f1d50fU, NULL))
   401         .WillOnce(Return(true));
   402     EXPECT_CALL(mock_handler, EndCompilationUnit(0))
   403         .WillOnce(Return(true));
   404   }
   406   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   407 }
   409 // On systems that store STABS in sections, string offsets are relative to
   410 // the beginning of that compilation unit's strings, marked with N_UNDF
   411 // symbols; see the comments for StabsReader::StabsReader.
   412 TEST_F(Stabs, Unitized) {
   413   stabs.set_endianness(kBigEndian);
   414   stabs.set_value_size(4);
   415   stabs
   416       .StartCU("antimony")
   417       .Stab(N_SO,   49, 26043, 0x7e259f1aU, "antimony")
   418       .Stab(N_FUN, 101, 63253, 0x7fbcccaeU, "arsenic")
   419       .Stab(N_SO,  124, 37175, 0x80b0014cU, "")
   420       .EndCU()
   421       .StartCU("aluminum")
   422       .Stab(N_SO,   72, 23084, 0x86756839U, "aluminum")
   423       .Stab(N_FUN,  59,  3305, 0xa8e120b0U, "selenium")
   424       .Stab(N_SO,  178, 56949, 0xbffff983U, "")
   425       .EndCU();
   427   {
   428     InSequence s;
   429     EXPECT_CALL(mock_handler,
   430                 StartCompilationUnit(StrEq("antimony"), 0x7e259f1aU, NULL))
   431         .WillOnce(Return(true));
   432     EXPECT_CALL(mock_handler, StartFunction(Eq("arsenic"), 0x7fbcccaeU))
   433         .WillOnce(Return(true));
   434     EXPECT_CALL(mock_handler, EndFunction(0x80b0014cU))
   435         .WillOnce(Return(true));
   436     EXPECT_CALL(mock_handler, EndCompilationUnit(0x80b0014cU))
   437         .WillOnce(Return(true));
   438     EXPECT_CALL(mock_handler,
   439                 StartCompilationUnit(StrEq("aluminum"), 0x86756839U, NULL))
   440         .WillOnce(Return(true));
   441     EXPECT_CALL(mock_handler, StartFunction(Eq("selenium"), 0xa8e120b0U))
   442         .WillOnce(Return(true));
   443     EXPECT_CALL(mock_handler, EndFunction(0xbffff983U))
   444         .WillOnce(Return(true));
   445     EXPECT_CALL(mock_handler, EndCompilationUnit(0xbffff983U))
   446         .WillOnce(Return(true));
   447   }
   449   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   450 }
   452 // On systems that store STABS entries in the real symbol table, the N_UNDF
   453 // entries have no special meaning, and shouldn't mess up the string
   454 // indices.
   455 TEST_F(Stabs, NonUnitized) {
   456   stabs.set_endianness(kLittleEndian);
   457   stabs.set_value_size(4);
   458   unitized = false;
   459   stabs
   460       .Stab(N_UNDF,    21, 11551, 0x9bad2b2e, "")
   461       .Stab(N_UNDF,    21, 11551, 0x9bad2b2e, "")
   462       .Stab(N_SO,      71, 45139, 0x11a97352, "Tanzania")
   463       .Stab(N_SO,     221, 41976, 0x21a97352, "");
   465   {
   466     InSequence s;
   467     EXPECT_CALL(mock_handler,
   468                 StartCompilationUnit(StrEq("Tanzania"),
   469                                      0x11a97352, NULL))
   470         .WillOnce(Return(true));
   471     EXPECT_CALL(mock_handler, EndCompilationUnit(0x21a97352))
   472         .WillOnce(Return(true));
   473   }
   475   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   476 }
   478 TEST_F(Stabs, FunctionEnd) {
   479   stabs.set_endianness(kLittleEndian);
   480   stabs.set_value_size(8);
   481   stabs
   482       .Stab(N_SO,    102, 62362, 0x52a830d644cd6942ULL, "compilation unit")
   483       // This function is terminated by the start of the next function.
   484       .Stab(N_FUN,   216, 38405, 0xbb5ab70ecdd23bfeULL, "function 1")
   485       // This function is terminated by an explicit end-of-function stab,
   486       // whose value is a size in bytes.
   487       .Stab(N_FUN,   240, 10973, 0xc954de9b8fb3e5e2ULL, "function 2")
   488       .Stab(N_FUN,    14, 36749, 0xc1ab,     "")
   489       // This function is terminated by the end of the compilation unit.
   490       .Stab(N_FUN,   143, 64514, 0xdff98c9a35386e1fULL, "function 3")
   491       .Stab(N_SO,    164, 60142, 0xfdacb856e78bbf57ULL, "");
   493   {
   494     InSequence s;
   495     EXPECT_CALL(mock_handler,
   496                 StartCompilationUnit(StrEq("compilation unit"),
   497                                      0x52a830d644cd6942ULL, NULL))
   498         .WillOnce(Return(true));
   499     EXPECT_CALL(mock_handler,
   500                 StartFunction(Eq("function 1"), 0xbb5ab70ecdd23bfeULL))
   501         .WillOnce(Return(true));
   502     EXPECT_CALL(mock_handler, EndFunction(0xc954de9b8fb3e5e2ULL))
   503         .WillOnce(Return(true));
   504     EXPECT_CALL(mock_handler,
   505                 StartFunction(Eq("function 2"), 0xc954de9b8fb3e5e2ULL))
   506         .WillOnce(Return(true));
   507     EXPECT_CALL(mock_handler, EndFunction(0xc954de9b8fb3e5e2ULL + 0xc1ab))
   508         .WillOnce(Return(true));
   509     EXPECT_CALL(mock_handler,
   510                 StartFunction(Eq("function 3"), 0xdff98c9a35386e1fULL))
   511         .WillOnce(Return(true));
   512     EXPECT_CALL(mock_handler, EndFunction(0xfdacb856e78bbf57ULL))
   513         .WillOnce(Return(true));
   514     EXPECT_CALL(mock_handler, EndCompilationUnit(0xfdacb856e78bbf57ULL))
   515         .WillOnce(Return(true));
   516   }
   518   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   519 }
   521 // On Mac OS X, SLINE records can appear before the FUN stab to which they
   522 // belong, and their values are absolute addresses, not offsets.
   523 TEST_F(Stabs, LeadingLine) {
   524   stabs.set_endianness(kBigEndian);
   525   stabs.set_value_size(4);
   526   stabs
   527       .Stab(N_SO,    179, 27357, 0x8adabc15, "build directory/")
   528       .Stab(N_SO,     52, 53058, 0x4c7e3bf4, "compilation unit")
   529       .Stab(N_SOL,   165, 12086, 0x6a797ca3, "source file name")
   530       .Stab(N_SLINE, 229, 20015, 0x4cb3d7e0, "")
   531       .Stab(N_SLINE,  89, 43802, 0x4cba8b88, "")
   532       .Stab(N_FUN,   251, 51639, 0xce1b98fa, "rutabaga")
   533       .Stab(N_FUN,   218, 16113, 0x5798,     "")
   534       .Stab(N_SO,     52, 53058, 0xd4af4415, "");
   536   {
   537     InSequence s;
   538     EXPECT_CALL(mock_handler,
   539                 StartCompilationUnit(StrEq("compilation unit"),
   540                                      0x4c7e3bf4, StrEq("build directory/")))
   541         .WillOnce(Return(true));
   542     EXPECT_CALL(mock_handler,
   543                 StartFunction(Eq("rutabaga"), 0xce1b98fa))
   544         .WillOnce(Return(true));
   545     EXPECT_CALL(mock_handler,
   546                 Line(0x4cb3d7e0, StrEq("source file name"), 20015))
   547         .WillOnce(Return(true));
   548     EXPECT_CALL(mock_handler,
   549                 Line(0x4cba8b88, StrEq("source file name"), 43802))
   550         .WillOnce(Return(true));
   551     EXPECT_CALL(mock_handler, EndFunction(0xce1b98fa + 0x5798))
   552         .WillOnce(Return(true));
   553     EXPECT_CALL(mock_handler, EndCompilationUnit(0xd4af4415))
   554         .WillOnce(Return(true));
   555   }
   557   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   558 }
   561 #if defined(HAVE_MACH_O_NLIST_H)
   562 // These tests have no meaning on non-Mach-O-based systems, as
   563 // only Mach-O uses N_SECT to represent public symbols.
   564 TEST_F(Stabs, OnePublicSymbol) {
   565   stabs.set_endianness(kLittleEndian);
   566   stabs.set_value_size(4);
   568   const uint32_t kExpectedAddress = 0x9000;
   569   const string kExpectedFunctionName("public_function");
   570   stabs
   571     .Stab(N_SECT, 1, 0, kExpectedAddress, kExpectedFunctionName);
   573   {
   574     InSequence s;
   575     EXPECT_CALL(mock_handler,
   576                 Extern(StrEq(kExpectedFunctionName),
   577                        kExpectedAddress))
   578         .WillOnce(Return(true));
   579   }
   580   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   581 }
   583 TEST_F(Stabs, TwoPublicSymbols) {
   584   stabs.set_endianness(kLittleEndian);
   585   stabs.set_value_size(4);
   587   const uint32_t kExpectedAddress1 = 0xB0B0B0B0;
   588   const string kExpectedFunctionName1("public_function");
   589   const uint32_t kExpectedAddress2 = 0xF0F0F0F0;
   590   const string kExpectedFunctionName2("something else");
   591   stabs
   592     .Stab(N_SECT, 1, 0, kExpectedAddress1, kExpectedFunctionName1)
   593     .Stab(N_SECT, 1, 0, kExpectedAddress2, kExpectedFunctionName2);
   595   {
   596     InSequence s;
   597     EXPECT_CALL(mock_handler,
   598                 Extern(StrEq(kExpectedFunctionName1),
   599                        kExpectedAddress1))
   600         .WillOnce(Return(true));
   601     EXPECT_CALL(mock_handler,
   602                 Extern(StrEq(kExpectedFunctionName2),
   603                        kExpectedAddress2))
   604         .WillOnce(Return(true));
   605   }
   606   ASSERT_TRUE(ApplyHandlerToMockStabsData());
   607 }
   609 #endif
   611 } // anonymous namespace

mercurial