toolkit/crashreporter/google-breakpad/src/common/module_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.

     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 // module_unittest.cc: Unit tests for google_breakpad::Module.
    34 #include <errno.h>
    35 #include <stdio.h>
    36 #include <stdlib.h>
    37 #include <string.h>
    39 #include <algorithm>
    40 #include <sstream>
    41 #include <string>
    43 #include "breakpad_googletest_includes.h"
    44 #include "common/module.h"
    45 #include "common/using_std_string.h"
    47 using google_breakpad::Module;
    48 using google_breakpad::ToUniqueString;
    49 using google_breakpad::ustr__ZDcfa;
    50 using std::stringstream;
    51 using std::vector;
    52 using testing::ContainerEq;
    54 static Module::Function *generate_duplicate_function(const string &name) {
    55   const Module::Address DUP_ADDRESS = 0xd35402aac7a7ad5cLL;
    56   const Module::Address DUP_SIZE = 0x200b26e605f99071LL;
    57   const Module::Address DUP_PARAMETER_SIZE = 0xf14ac4fed48c4a99LL;
    59   Module::Function *function = new(Module::Function);
    60   function->name = name;
    61   function->address = DUP_ADDRESS;
    62   function->size = DUP_SIZE;
    63   function->parameter_size = DUP_PARAMETER_SIZE;
    64   return function;
    65 }
    67 #define MODULE_NAME "name with spaces"
    68 #define MODULE_OS "os-name"
    69 #define MODULE_ARCH "architecture"
    70 #define MODULE_ID "id-string"
    72 TEST(Write, Header) {
    73   stringstream s;
    74   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
    75   m.Write(s, ALL_SYMBOL_DATA);
    76   string contents = s.str();
    77   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n",
    78                contents.c_str());
    79 }
    81 TEST(Write, OneLineFunc) {
    82   stringstream s;
    83   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
    85   Module::File *file = m.FindFile("file_name.cc");
    86   Module::Function *function = new(Module::Function);
    87   function->name = "function_name";
    88   function->address = 0xe165bf8023b9d9abLL;
    89   function->size = 0x1e4bb0eb1cbf5b09LL;
    90   function->parameter_size = 0x772beee89114358aLL;
    91   Module::Line line = { 0xe165bf8023b9d9abLL, 0x1e4bb0eb1cbf5b09LL,
    92                         file, 67519080 };
    93   function->lines.push_back(line);
    94   m.AddFunction(function);
    96   m.Write(s, ALL_SYMBOL_DATA);
    97   string contents = s.str();
    98   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
    99                "FILE 0 file_name.cc\n"
   100                "FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a"
   101                " function_name\n"
   102                "e165bf8023b9d9ab 1e4bb0eb1cbf5b09 67519080 0\n",
   103                contents.c_str());
   104 }
   106 TEST(Write, RelativeLoadAddress) {
   107   stringstream s;
   108   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   110   // Some source files.  We will expect to see them in lexicographic order.
   111   Module::File *file1 = m.FindFile("filename-b.cc");
   112   Module::File *file2 = m.FindFile("filename-a.cc");
   114   // A function.
   115   Module::Function *function = new(Module::Function);
   116   function->name = "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)";
   117   function->address = 0xbec774ea5dd935f3LL;
   118   function->size = 0x2922088f98d3f6fcLL;
   119   function->parameter_size = 0xe5e9aa008bd5f0d0LL;
   121   // Some source lines.  The module should not sort these.
   122   Module::Line line1 = { 0xbec774ea5dd935f3LL, 0x1c2be6d6c5af2611LL,
   123                          file1, 41676901 };
   124   Module::Line line2 = { 0xdaf35bc123885c04LL, 0xcf621b8d324d0ebLL,
   125                          file2, 67519080 };
   126   function->lines.push_back(line2);
   127   function->lines.push_back(line1);
   129   m.AddFunction(function);
   131   // Some stack information.
   132   Module::StackFrameEntry *entry = new Module::StackFrameEntry();
   133   entry->address = 0x30f9e5c83323973dULL;
   134   entry->size = 0x49fc9ca7c7c13dc2ULL;
   135   entry->initial_rules[ustr__ZDcfa()] = Module::Expr("he was a handsome man");
   136   entry->initial_rules[ToUniqueString("and")] =
   137       Module::Expr("what i want to know is");
   138   entry->initial_rules[ToUniqueString("stallion")] =
   139       Module::Expr(ToUniqueString("and break"), 8, false);
   140   entry->initial_rules[ToUniqueString("onetwothreefourfive")] =
   141       Module::Expr(ToUniqueString("pigeonsjustlikethat"), 42, true);
   142   entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("how")] =
   143       Module::Expr("do you like your blueeyed boy");
   144   entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("Mister")] =
   145       Module::Expr("Death");
   146   m.AddStackFrameEntry(entry);
   148   // Set the load address.  Doing this after adding all the data to
   149   // the module must work fine.
   150   m.SetLoadAddress(0x2ab698b0b6407073LL);
   152   m.Write(s, ALL_SYMBOL_DATA);
   153   string contents = s.str();
   154   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   155                "FILE 0 filename-a.cc\n"
   156                "FILE 1 filename-b.cc\n"
   157                "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0"
   158                " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n"
   159                "b03cc3106d47eb91 cf621b8d324d0eb 67519080 0\n"
   160                "9410dc39a798c580 1c2be6d6c5af2611 41676901 1\n"
   161                "STACK CFI INIT 6434d177ce326ca 49fc9ca7c7c13dc2"
   162                " .cfa: he was a handsome man"
   163                " and: what i want to know is"
   164                " onetwothreefourfive: pigeonsjustlikethat 42 + ^"
   165                " stallion: and break 8 +\n"
   166                "STACK CFI 6434d177ce326cb"
   167                " Mister: Death"
   168                " how: do you like your blueeyed boy\n",
   169                contents.c_str());
   170 }
   172 TEST(Write, OmitUnusedFiles) {
   173   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   175   // Create some source files.
   176   Module::File *file1 = m.FindFile("filename1");
   177   m.FindFile("filename2");  // not used by any line
   178   Module::File *file3 = m.FindFile("filename3");
   180   // Create a function.
   181   Module::Function *function = new(Module::Function);
   182   function->name = "function_name";
   183   function->address = 0x9b926d464f0b9384LL;
   184   function->size = 0x4f524a4ba795e6a6LL;
   185   function->parameter_size = 0xbbe8133a6641c9b7LL;
   187   // Source files that refer to some files, but not others.
   188   Module::Line line1 = { 0x595fa44ebacc1086LL, 0x1e1e0191b066c5b3LL,
   189                          file1, 137850127 };
   190   Module::Line line2 = { 0x401ce8c8a12d25e3LL, 0x895751c41b8d2ce2LL,
   191                          file3, 28113549 };
   192   function->lines.push_back(line1);
   193   function->lines.push_back(line2);
   194   m.AddFunction(function);
   196   m.AssignSourceIds();
   198   vector<Module::File *> vec;
   199   m.GetFiles(&vec);
   200   EXPECT_EQ((size_t) 3, vec.size());
   201   EXPECT_STREQ("filename1", vec[0]->name.c_str());
   202   EXPECT_NE(-1, vec[0]->source_id);
   203   // Expect filename2 not to be used.
   204   EXPECT_STREQ("filename2", vec[1]->name.c_str());
   205   EXPECT_EQ(-1, vec[1]->source_id);
   206   EXPECT_STREQ("filename3", vec[2]->name.c_str());
   207   EXPECT_NE(-1, vec[2]->source_id);
   209   stringstream s;
   210   m.Write(s, ALL_SYMBOL_DATA);
   211   string contents = s.str();
   212   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   213                "FILE 0 filename1\n"
   214                "FILE 1 filename3\n"
   215                "FUNC 9b926d464f0b9384 4f524a4ba795e6a6 bbe8133a6641c9b7"
   216                " function_name\n"
   217                "595fa44ebacc1086 1e1e0191b066c5b3 137850127 0\n"
   218                "401ce8c8a12d25e3 895751c41b8d2ce2 28113549 1\n",
   219                contents.c_str());
   220 }
   222 TEST(Write, NoCFI) {
   223   stringstream s;
   224   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   226   // Some source files.  We will expect to see them in lexicographic order.
   227   Module::File *file1 = m.FindFile("filename.cc");
   229   // A function.
   230   Module::Function *function = new(Module::Function);
   231   function->name = "A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)";
   232   function->address = 0xbec774ea5dd935f3LL;
   233   function->size = 0x2922088f98d3f6fcLL;
   234   function->parameter_size = 0xe5e9aa008bd5f0d0LL;
   236   // Some source lines.  The module should not sort these.
   237   Module::Line line1 = { 0xbec774ea5dd935f3LL, 0x1c2be6d6c5af2611LL,
   238                          file1, 41676901 };
   239   function->lines.push_back(line1);
   241   m.AddFunction(function);
   243   // Some stack information.
   244   Module::StackFrameEntry *entry = new Module::StackFrameEntry();
   245   entry->address = 0x30f9e5c83323973dULL;
   246   entry->size = 0x49fc9ca7c7c13dc2ULL;
   247   entry->initial_rules[ustr__ZDcfa()] = Module::Expr("he was a handsome man");
   248   entry->initial_rules[ToUniqueString("and")] =
   249       Module::Expr("what i want to know is");
   250   entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("how")] =
   251       Module::Expr("do you like your blueeyed boy");
   252   entry->rule_changes[0x30f9e5c83323973eULL][ToUniqueString("Mister")] =
   253       Module::Expr("Death");
   254   m.AddStackFrameEntry(entry);
   256   // Set the load address.  Doing this after adding all the data to
   257   // the module must work fine.
   258   m.SetLoadAddress(0x2ab698b0b6407073LL);
   260   m.Write(s, NO_CFI);
   261   string contents = s.str();
   262   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   263                "FILE 0 filename.cc\n"
   264                "FUNC 9410dc39a798c580 2922088f98d3f6fc e5e9aa008bd5f0d0"
   265                " A_FLIBBERTIJIBBET::a_will_o_the_wisp(a clown)\n"
   266                "9410dc39a798c580 1c2be6d6c5af2611 41676901 0\n",
   267                contents.c_str());
   268 }
   270 TEST(Construct, AddFunctions) {
   271   stringstream s;
   272   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   274   // Two functions.
   275   Module::Function *function1 = new(Module::Function);
   276   function1->name = "_without_form";
   277   function1->address = 0xd35024aa7ca7da5cLL;
   278   function1->size = 0x200b26e605f99071LL;
   279   function1->parameter_size = 0xf14ac4fed48c4a99LL;
   281   Module::Function *function2 = new(Module::Function);
   282   function2->name = "_and_void";
   283   function2->address = 0x2987743d0b35b13fLL;
   284   function2->size = 0xb369db048deb3010LL;
   285   function2->parameter_size = 0x938e556cb5a79988LL;
   287   // Put them in a vector.
   288   vector<Module::Function *> vec;
   289   vec.push_back(function1);
   290   vec.push_back(function2);
   292   m.AddFunctions(vec.begin(), vec.end());
   294   m.Write(s, ALL_SYMBOL_DATA);
   295   string contents = s.str();
   296   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   297                "FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988"
   298                " _and_void\n"
   299                "FUNC d35024aa7ca7da5c 200b26e605f99071 f14ac4fed48c4a99"
   300                " _without_form\n",
   301                contents.c_str());
   303   // Check that m.GetFunctions returns the functions we expect.
   304   vec.clear();
   305   m.GetFunctions(&vec, vec.end());
   306   EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function1));
   307   EXPECT_TRUE(vec.end() != find(vec.begin(), vec.end(), function2));
   308   EXPECT_EQ((size_t) 2, vec.size());
   309 }
   311 TEST(Construct, AddFrames) {
   312   stringstream s;
   313   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   315   // First STACK CFI entry, with no initial rules or deltas.
   316   Module::StackFrameEntry *entry1 = new Module::StackFrameEntry();
   317   entry1->address = 0xddb5f41285aa7757ULL;
   318   entry1->size = 0x1486493370dc5073ULL;
   319   m.AddStackFrameEntry(entry1);
   321   // Second STACK CFI entry, with initial rules but no deltas.
   322   Module::StackFrameEntry *entry2 = new Module::StackFrameEntry();
   323   entry2->address = 0x8064f3af5e067e38ULL;
   324   entry2->size = 0x0de2a5ee55509407ULL;
   325   entry2->initial_rules[ustr__ZDcfa()] =
   326       Module::Expr("I think that I shall never see");
   327   entry2->initial_rules[ToUniqueString("stromboli")] =
   328       Module::Expr("a poem lovely as a tree");
   329   entry2->initial_rules[ToUniqueString("cannoli")] =
   330       Module::Expr("a tree whose hungry mouth is prest");
   331   m.AddStackFrameEntry(entry2);
   333   // Third STACK CFI entry, with initial rules and deltas.
   334   Module::StackFrameEntry *entry3 = new Module::StackFrameEntry();
   335   entry3->address = 0x5e8d0db0a7075c6cULL;
   336   entry3->size = 0x1c7edb12a7aea229ULL;
   337   entry3->initial_rules[ustr__ZDcfa()] = Module::Expr("Whose woods are these");
   338   entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("calzone")] =
   339     Module::Expr("the village though");
   340   entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("cannoli")] =
   341     Module::Expr("he will not see me stopping here");
   342   entry3->rule_changes[0x36682fad3763ffffULL][ToUniqueString("stromboli")] =
   343     Module::Expr("his house is in");
   344   entry3->rule_changes[0x36682fad3763ffffULL][ustr__ZDcfa()] =
   345     Module::Expr("I think I know");
   346   m.AddStackFrameEntry(entry3);
   348   // Check that Write writes STACK CFI records properly.
   349   m.Write(s, ALL_SYMBOL_DATA);
   350   string contents = s.str();
   351   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   352                "STACK CFI INIT 5e8d0db0a7075c6c 1c7edb12a7aea229"
   353                " .cfa: Whose woods are these\n"
   354                "STACK CFI 36682fad3763ffff"
   355                " .cfa: I think I know"
   356                " stromboli: his house is in\n"
   357                "STACK CFI 47ceb0f63c269d7f"
   358                " calzone: the village though"
   359                " cannoli: he will not see me stopping here\n"
   360                "STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
   361                " .cfa: I think that I shall never see"
   362                " cannoli: a tree whose hungry mouth is prest"
   363                " stromboli: a poem lovely as a tree\n"
   364                "STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n",
   365                contents.c_str());
   367   // Check that GetStackFrameEntries works.
   368   vector<Module::StackFrameEntry *> entries;
   369   m.GetStackFrameEntries(&entries);
   370   ASSERT_EQ(3U, entries.size());
   371   // Check first entry.
   372   EXPECT_EQ(0x5e8d0db0a7075c6cULL, entries[0]->address);
   373   EXPECT_EQ(0x1c7edb12a7aea229ULL, entries[0]->size);
   374   Module::RuleMap entry1_initial;
   375   entry1_initial[ustr__ZDcfa()] = Module::Expr("Whose woods are these");
   376   EXPECT_THAT(entries[0]->initial_rules, ContainerEq(entry1_initial));
   377   Module::RuleChangeMap entry1_changes;
   378   entry1_changes[0x36682fad3763ffffULL][ustr__ZDcfa()] =
   379       Module::Expr("I think I know");
   380   entry1_changes[0x36682fad3763ffffULL][ToUniqueString("stromboli")] =
   381       Module::Expr("his house is in");
   382   entry1_changes[0x47ceb0f63c269d7fULL][ToUniqueString("calzone")] =
   383       Module::Expr("the village though");
   384   entry1_changes[0x47ceb0f63c269d7fULL][ToUniqueString("cannoli")] =
   385       Module::Expr("he will not see me stopping here");
   386   EXPECT_THAT(entries[0]->rule_changes, ContainerEq(entry1_changes));
   387   // Check second entry.
   388   EXPECT_EQ(0x8064f3af5e067e38ULL, entries[1]->address);
   389   EXPECT_EQ(0x0de2a5ee55509407ULL, entries[1]->size);
   390   ASSERT_EQ(3U, entries[1]->initial_rules.size());
   391   Module::RuleMap entry2_initial;
   392   entry2_initial[ustr__ZDcfa()] =
   393       Module::Expr("I think that I shall never see");
   394   entry2_initial[ToUniqueString("stromboli")] =
   395       Module::Expr("a poem lovely as a tree");
   396   entry2_initial[ToUniqueString("cannoli")] =
   397       Module::Expr("a tree whose hungry mouth is prest");
   398   EXPECT_THAT(entries[1]->initial_rules, ContainerEq(entry2_initial));
   399   ASSERT_EQ(0U, entries[1]->rule_changes.size());
   400   // Check third entry.
   401   EXPECT_EQ(0xddb5f41285aa7757ULL, entries[2]->address);
   402   EXPECT_EQ(0x1486493370dc5073ULL, entries[2]->size);
   403   ASSERT_EQ(0U, entries[2]->initial_rules.size());
   404   ASSERT_EQ(0U, entries[2]->rule_changes.size());
   405 }
   407 TEST(Construct, UniqueFiles) {
   408   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   409   Module::File *file1 = m.FindFile("foo");
   410   Module::File *file2 = m.FindFile(string("bar"));
   411   Module::File *file3 = m.FindFile(string("foo"));
   412   Module::File *file4 = m.FindFile("bar");
   413   EXPECT_NE(file1, file2);
   414   EXPECT_EQ(file1, file3);
   415   EXPECT_EQ(file2, file4);
   416   EXPECT_EQ(file1, m.FindExistingFile("foo"));
   417   EXPECT_TRUE(m.FindExistingFile("baz") == NULL);
   418 }
   420 TEST(Construct, DuplicateFunctions) {
   421   stringstream s;
   422   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   424   // Two functions.
   425   Module::Function *function1 = generate_duplicate_function("_without_form");
   426   Module::Function *function2 = generate_duplicate_function("_without_form");
   428   m.AddFunction(function1);
   429   m.AddFunction(function2);
   431   m.Write(s, ALL_SYMBOL_DATA);
   432   string contents = s.str();
   433   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   434                "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
   435                " _without_form\n",
   436                contents.c_str());
   437 }
   439 TEST(Construct, FunctionsWithSameAddress) {
   440   stringstream s;
   441   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   443   // Two functions.
   444   Module::Function *function1 = generate_duplicate_function("_without_form");
   445   Module::Function *function2 = generate_duplicate_function("_and_void");
   447   m.AddFunction(function1);
   448   m.AddFunction(function2);
   450   m.Write(s, ALL_SYMBOL_DATA);
   451   string contents = s.str();
   452   EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
   453                "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
   454                " _and_void\n"
   455                "FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
   456                " _without_form\n",
   457                contents.c_str());
   458 }
   460 // Externs should be written out as PUBLIC records, sorted by
   461 // address.
   462 TEST(Construct, Externs) {
   463   stringstream s;
   464   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   466   // Two externs.
   467   Module::Extern *extern1 = new(Module::Extern);
   468   extern1->address = 0xffff;
   469   extern1->name = "_abc";
   470   Module::Extern *extern2 = new(Module::Extern);
   471   extern2->address = 0xaaaa;
   472   extern2->name = "_xyz";
   474   m.AddExtern(extern1);
   475   m.AddExtern(extern2);
   477   m.Write(s, ALL_SYMBOL_DATA);
   478   string contents = s.str();
   480   EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
   481                MODULE_ID " " MODULE_NAME "\n"
   482                "PUBLIC aaaa 0 _xyz\n"
   483                "PUBLIC ffff 0 _abc\n",
   484                contents.c_str());
   485 }
   487 // Externs with the same address should only keep the first entry
   488 // added.
   489 TEST(Construct, DuplicateExterns) {
   490   stringstream s;
   491   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   493   // Two externs.
   494   Module::Extern *extern1 = new(Module::Extern);
   495   extern1->address = 0xffff;
   496   extern1->name = "_xyz";
   497   Module::Extern *extern2 = new(Module::Extern);
   498   extern2->address = 0xffff;
   499   extern2->name = "_abc";
   501   m.AddExtern(extern1);
   502   m.AddExtern(extern2);
   504   m.Write(s, ALL_SYMBOL_DATA);
   505   string contents = s.str();
   507   EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
   508                MODULE_ID " " MODULE_NAME "\n"
   509                "PUBLIC ffff 0 _xyz\n",
   510                contents.c_str());
   511 }
   513 TEST(Lookup, Function) {
   514   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   516   Module::Function *function1 = new(Module::Function);
   517   function1->name = "_abc1";
   518   function1->address = 0x1000;
   519   function1->size = 0x900;
   520   function1->parameter_size = 0x0;
   522   Module::Function *function2 = new(Module::Function);
   523   function2->name = "_xyz2";
   524   function2->address = 0x2000;
   525   function2->size = 0x900;
   526   function2->parameter_size = 0x0;
   528   Module::Function *function3 = new(Module::Function);
   529   function3->name = "_def3";
   530   function3->address = 0x3000;
   531   function3->size = 0x900;
   532   function3->parameter_size = 0x0;
   534   // Put them in a vector.
   535   vector<Module::Function *> vec;
   536   vec.push_back(function1);
   537   vec.push_back(function2);
   538   vec.push_back(function3);
   540   m.AddFunctions(vec.begin(), vec.end());
   542   // Try looking up functions by address.
   543   Module::Function* f = m.FindFunctionByAddress(0x1000);
   544   EXPECT_EQ(function1, f);
   545   f = m.FindFunctionByAddress(0x18FF);
   546   EXPECT_EQ(function1, f);
   548   f = m.FindFunctionByAddress(0x1900);
   549   EXPECT_EQ((Module::Function*)NULL, f);
   550   f = m.FindFunctionByAddress(0x1A00);
   551   EXPECT_EQ((Module::Function*)NULL, f);
   553   f = m.FindFunctionByAddress(0x2000);
   554   EXPECT_EQ(function2, f);
   555   f = m.FindFunctionByAddress(0x28FF);
   556   EXPECT_EQ(function2, f);
   558   f = m.FindFunctionByAddress(0x3000);
   559   EXPECT_EQ(function3, f);
   560   f = m.FindFunctionByAddress(0x38FF);
   561   EXPECT_EQ(function3, f);
   563   f = m.FindFunctionByAddress(0x3900);
   564   EXPECT_EQ((Module::Function*)NULL, f);
   565   f = m.FindFunctionByAddress(0x3A00);
   566   EXPECT_EQ((Module::Function*)NULL, f);
   567 }
   569 TEST(Lookup, Externs) {
   570   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   572   // Two externs.
   573   Module::Extern* extern1 = new(Module::Extern);
   574   extern1->address = 0x1000;
   575   extern1->name = "_abc";
   576   Module::Extern* extern2 = new(Module::Extern);
   577   extern2->address = 0x2000;
   578   extern2->name = "_xyz";
   580   m.AddExtern(extern1);
   581   m.AddExtern(extern2);
   583   Module::Extern* e = m.FindExternByAddress(0xFFF);
   584   EXPECT_EQ((Module::Extern*)NULL, e);
   586   e = m.FindExternByAddress(0x1000);
   587   EXPECT_EQ(extern1, e);
   588   e = m.FindExternByAddress(0x1900);
   589   EXPECT_EQ(extern1, e);
   590   e = m.FindExternByAddress(0x1FFF);
   591   EXPECT_EQ(extern1, e);
   593   e = m.FindExternByAddress(0x2000);
   594   EXPECT_EQ(extern2, e);
   595   e = m.FindExternByAddress(0x2900);
   596   EXPECT_EQ(extern2, e);
   597   e = m.FindExternByAddress(0xFFFFFFFF);
   598   EXPECT_EQ(extern2, e);
   599 }
   601 TEST(Lookup, StackFrameEntries) {
   602   Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
   604   // First STACK CFI entry, with no initial rules or deltas.
   605   Module::StackFrameEntry *entry1 = new Module::StackFrameEntry();
   606   entry1->address = 0x2000;
   607   entry1->size = 0x900;
   608   m.AddStackFrameEntry(entry1);
   610   // Second STACK CFI entry, with initial rules but no deltas.
   611   Module::StackFrameEntry *entry2 = new Module::StackFrameEntry();
   612   entry2->address = 0x3000;
   613   entry2->size = 0x900;
   614   entry2->initial_rules[ustr__ZDcfa()] =
   615       Module::Expr("I think that I shall never see");
   616   entry2->initial_rules[ToUniqueString("stromboli")] =
   617       Module::Expr("a poem lovely as a tree");
   618   entry2->initial_rules[ToUniqueString("cannoli")] =
   619       Module::Expr("a tree whose hungry mouth is prest");
   620   m.AddStackFrameEntry(entry2);
   622   // Third STACK CFI entry, with initial rules and deltas.
   623   Module::StackFrameEntry *entry3 = new Module::StackFrameEntry();
   624   entry3->address = 0x1000;
   625   entry3->size = 0x900;
   626   entry3->initial_rules[ustr__ZDcfa()] = Module::Expr("Whose woods are these");
   627   entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("calzone")] =
   628     Module::Expr("the village though");
   629   entry3->rule_changes[0x47ceb0f63c269d7fULL][ToUniqueString("cannoli")] =
   630     Module::Expr("he will not see me stopping here");
   631   entry3->rule_changes[0x36682fad3763ffffULL][ToUniqueString("stromboli")] =
   632     Module::Expr("his house is in");
   633   entry3->rule_changes[0x36682fad3763ffffULL][ustr__ZDcfa()] =
   634     Module::Expr("I think I know");
   635   m.AddStackFrameEntry(entry3);
   637   Module::StackFrameEntry* s = m.FindStackFrameEntryByAddress(0x1000);
   638   EXPECT_EQ(entry3, s);
   639   s = m.FindStackFrameEntryByAddress(0x18FF);
   640   EXPECT_EQ(entry3, s);
   642   s = m.FindStackFrameEntryByAddress(0x1900);
   643   EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   644   s = m.FindStackFrameEntryByAddress(0x1A00);
   645   EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   647   s = m.FindStackFrameEntryByAddress(0x2000);
   648   EXPECT_EQ(entry1, s);
   649   s = m.FindStackFrameEntryByAddress(0x28FF);
   650   EXPECT_EQ(entry1, s);
   652   s = m.FindStackFrameEntryByAddress(0x3000);
   653   EXPECT_EQ(entry2, s);
   654   s = m.FindStackFrameEntryByAddress(0x38FF);
   655   EXPECT_EQ(entry2, s);
   657   s = m.FindStackFrameEntryByAddress(0x3900);
   658   EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   659   s = m.FindStackFrameEntryByAddress(0x3A00);
   660   EXPECT_EQ((Module::StackFrameEntry*)NULL, s);
   661 }

mercurial