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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial