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.

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

mercurial