Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 | // synth_minidump_unittest.cc: Unit tests for google_breakpad::SynthMinidump |
michael@0 | 33 | // classes. |
michael@0 | 34 | |
michael@0 | 35 | #include <sstream> |
michael@0 | 36 | #include <string> |
michael@0 | 37 | |
michael@0 | 38 | #include "breakpad_googletest_includes.h" |
michael@0 | 39 | #include "common/using_std_string.h" |
michael@0 | 40 | #include "google_breakpad/common/minidump_format.h" |
michael@0 | 41 | #include "processor/synth_minidump.h" |
michael@0 | 42 | #include "processor/synth_minidump_unittest_data.h" |
michael@0 | 43 | |
michael@0 | 44 | using google_breakpad::SynthMinidump::Context; |
michael@0 | 45 | using google_breakpad::SynthMinidump::Dump; |
michael@0 | 46 | using google_breakpad::SynthMinidump::Exception; |
michael@0 | 47 | using google_breakpad::SynthMinidump::List; |
michael@0 | 48 | using google_breakpad::SynthMinidump::Memory; |
michael@0 | 49 | using google_breakpad::SynthMinidump::Module; |
michael@0 | 50 | using google_breakpad::SynthMinidump::Section; |
michael@0 | 51 | using google_breakpad::SynthMinidump::Stream; |
michael@0 | 52 | using google_breakpad::SynthMinidump::String; |
michael@0 | 53 | using google_breakpad::SynthMinidump::SystemInfo; |
michael@0 | 54 | using google_breakpad::test_assembler::kBigEndian; |
michael@0 | 55 | using google_breakpad::test_assembler::kLittleEndian; |
michael@0 | 56 | using google_breakpad::test_assembler::Label; |
michael@0 | 57 | |
michael@0 | 58 | TEST(Section, Simple) { |
michael@0 | 59 | Dump dump(0); |
michael@0 | 60 | Section section(dump); |
michael@0 | 61 | section.L32(0x12345678); |
michael@0 | 62 | section.Finish(0); |
michael@0 | 63 | string contents; |
michael@0 | 64 | ASSERT_TRUE(section.GetContents(&contents)); |
michael@0 | 65 | EXPECT_EQ(string("\x78\x56\x34\x12", 4), contents); |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | TEST(Section, CiteLocationIn) { |
michael@0 | 69 | Dump dump(0, kBigEndian); |
michael@0 | 70 | Section section1(dump), section2(dump); |
michael@0 | 71 | section1.Append("order"); |
michael@0 | 72 | section2.Append("mayhem"); |
michael@0 | 73 | section2.Finish(0x32287ec2); |
michael@0 | 74 | section2.CiteLocationIn(§ion1); |
michael@0 | 75 | string contents; |
michael@0 | 76 | ASSERT_TRUE(section1.GetContents(&contents)); |
michael@0 | 77 | string expected("order\0\0\0\x06\x32\x28\x7e\xc2", 13); |
michael@0 | 78 | EXPECT_EQ(expected, contents); |
michael@0 | 79 | } |
michael@0 | 80 | |
michael@0 | 81 | TEST(Stream, CiteStreamIn) { |
michael@0 | 82 | Dump dump(0, kLittleEndian); |
michael@0 | 83 | Stream stream(dump, 0x40cae2b3); |
michael@0 | 84 | Section section(dump); |
michael@0 | 85 | stream.Append("stream contents"); |
michael@0 | 86 | section.Append("section contents"); |
michael@0 | 87 | stream.Finish(0x41424344); |
michael@0 | 88 | stream.CiteStreamIn(§ion); |
michael@0 | 89 | string contents; |
michael@0 | 90 | ASSERT_TRUE(section.GetContents(&contents)); |
michael@0 | 91 | string expected("section contents" |
michael@0 | 92 | "\xb3\xe2\xca\x40" |
michael@0 | 93 | "\x0f\0\0\0" |
michael@0 | 94 | "\x44\x43\x42\x41", |
michael@0 | 95 | 16 + 4 + 4 + 4); |
michael@0 | 96 | EXPECT_EQ(expected, contents); |
michael@0 | 97 | } |
michael@0 | 98 | |
michael@0 | 99 | TEST(Memory, CiteMemoryIn) { |
michael@0 | 100 | Dump dump(0, kBigEndian); |
michael@0 | 101 | Memory memory(dump, 0x76d010874ab019f9ULL); |
michael@0 | 102 | Section section(dump); |
michael@0 | 103 | memory.Append("memory contents"); |
michael@0 | 104 | section.Append("section contents"); |
michael@0 | 105 | memory.Finish(0x51525354); |
michael@0 | 106 | memory.CiteMemoryIn(§ion); |
michael@0 | 107 | string contents; |
michael@0 | 108 | ASSERT_TRUE(section.GetContents(&contents)); |
michael@0 | 109 | string expected("section contents" |
michael@0 | 110 | "\x76\xd0\x10\x87\x4a\xb0\x19\xf9" |
michael@0 | 111 | "\0\0\0\x0f" |
michael@0 | 112 | "\x51\x52\x53\x54", |
michael@0 | 113 | 16 + 8 + 4 + 4); |
michael@0 | 114 | EXPECT_EQ(contents, expected); |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | TEST(Memory, Here) { |
michael@0 | 118 | Dump dump(0, kBigEndian); |
michael@0 | 119 | Memory memory(dump, 0x89979731eb060ed4ULL); |
michael@0 | 120 | memory.Append(1729, 42); |
michael@0 | 121 | Label l = memory.Here(); |
michael@0 | 122 | ASSERT_EQ(0x89979731eb060ed4ULL + 1729, l.Value()); |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | TEST(Context, X86) { |
michael@0 | 126 | Dump dump(0, kLittleEndian); |
michael@0 | 127 | assert(x86_raw_context.context_flags & MD_CONTEXT_X86); |
michael@0 | 128 | Context context(dump, x86_raw_context); |
michael@0 | 129 | string contents; |
michael@0 | 130 | ASSERT_TRUE(context.GetContents(&contents)); |
michael@0 | 131 | EXPECT_EQ(sizeof(x86_expected_contents), contents.size()); |
michael@0 | 132 | EXPECT_TRUE(memcmp(contents.data(), x86_expected_contents, contents.size()) |
michael@0 | 133 | == 0); |
michael@0 | 134 | } |
michael@0 | 135 | |
michael@0 | 136 | TEST(Context, ARM) { |
michael@0 | 137 | Dump dump(0, kLittleEndian); |
michael@0 | 138 | assert(arm_raw_context.context_flags & MD_CONTEXT_ARM); |
michael@0 | 139 | Context context(dump, arm_raw_context); |
michael@0 | 140 | string contents; |
michael@0 | 141 | ASSERT_TRUE(context.GetContents(&contents)); |
michael@0 | 142 | EXPECT_EQ(sizeof(arm_expected_contents), contents.size()); |
michael@0 | 143 | EXPECT_TRUE(memcmp(contents.data(), arm_expected_contents, contents.size()) |
michael@0 | 144 | == 0); |
michael@0 | 145 | } |
michael@0 | 146 | |
michael@0 | 147 | TEST(ContextDeathTest, X86BadFlags) { |
michael@0 | 148 | Dump dump(0, kLittleEndian); |
michael@0 | 149 | MDRawContextX86 raw; |
michael@0 | 150 | raw.context_flags = MD_CONTEXT_AMD64; |
michael@0 | 151 | ASSERT_DEATH(Context context(dump, raw);, |
michael@0 | 152 | "context\\.context_flags & (0x[0-9a-f]+|MD_CONTEXT_X86)"); |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | TEST(ContextDeathTest, X86BadEndianness) { |
michael@0 | 156 | Dump dump(0, kBigEndian); |
michael@0 | 157 | MDRawContextX86 raw; |
michael@0 | 158 | raw.context_flags = MD_CONTEXT_X86; |
michael@0 | 159 | ASSERT_DEATH(Context context(dump, raw);, |
michael@0 | 160 | "dump\\.endianness\\(\\) == kLittleEndian"); |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | TEST(Thread, Simple) { |
michael@0 | 164 | Dump dump(0, kLittleEndian); |
michael@0 | 165 | Context context(dump, x86_raw_context); |
michael@0 | 166 | context.Finish(0x8665da0c); |
michael@0 | 167 | Memory stack(dump, 0xaad55a93cc3c0efcULL); |
michael@0 | 168 | stack.Append("stack contents"); |
michael@0 | 169 | stack.Finish(0xe08cdbd1); |
michael@0 | 170 | google_breakpad::SynthMinidump::Thread thread( |
michael@0 | 171 | dump, 0x3d7ec360, stack, context, |
michael@0 | 172 | 0x3593f44d, // suspend count |
michael@0 | 173 | 0xab352b82, // priority class |
michael@0 | 174 | 0x2753d838, // priority |
michael@0 | 175 | 0xeb2de4be3f29e3e9ULL); // thread environment block |
michael@0 | 176 | string contents; |
michael@0 | 177 | ASSERT_TRUE(thread.GetContents(&contents)); |
michael@0 | 178 | static const uint8_t expected_bytes[] = { |
michael@0 | 179 | 0x60, 0xc3, 0x7e, 0x3d, // thread id |
michael@0 | 180 | 0x4d, 0xf4, 0x93, 0x35, // suspend count |
michael@0 | 181 | 0x82, 0x2b, 0x35, 0xab, // priority class |
michael@0 | 182 | 0x38, 0xd8, 0x53, 0x27, // priority |
michael@0 | 183 | 0xe9, 0xe3, 0x29, 0x3f, 0xbe, 0xe4, 0x2d, 0xeb, // thread environment block |
michael@0 | 184 | 0xfc, 0x0e, 0x3c, 0xcc, 0x93, 0x5a, 0xd5, 0xaa, // stack address |
michael@0 | 185 | 0x0e, 0x00, 0x00, 0x00, // stack size |
michael@0 | 186 | 0xd1, 0xdb, 0x8c, 0xe0, // stack MDRVA |
michael@0 | 187 | 0xcc, 0x02, 0x00, 0x00, // context size |
michael@0 | 188 | 0x0c, 0xda, 0x65, 0x86 // context MDRVA |
michael@0 | 189 | }; |
michael@0 | 190 | EXPECT_EQ(sizeof(expected_bytes), contents.size()); |
michael@0 | 191 | EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0); |
michael@0 | 192 | } |
michael@0 | 193 | |
michael@0 | 194 | TEST(Exception, Simple) { |
michael@0 | 195 | Dump dump(0, kLittleEndian); |
michael@0 | 196 | Context context(dump, x86_raw_context); |
michael@0 | 197 | context.Finish(0x8665da0c); |
michael@0 | 198 | |
michael@0 | 199 | Exception exception(dump, context, |
michael@0 | 200 | 0x1234abcd, // thread id |
michael@0 | 201 | 0xdcba4321, // exception code |
michael@0 | 202 | 0xf0e0d0c0, // exception flags |
michael@0 | 203 | 0x0919a9b9c9d9e9f9ULL); // exception address |
michael@0 | 204 | string contents; |
michael@0 | 205 | ASSERT_TRUE(exception.GetContents(&contents)); |
michael@0 | 206 | static const uint8_t expected_bytes[] = { |
michael@0 | 207 | 0xcd, 0xab, 0x34, 0x12, // thread id |
michael@0 | 208 | 0x00, 0x00, 0x00, 0x00, // __align |
michael@0 | 209 | 0x21, 0x43, 0xba, 0xdc, // exception code |
michael@0 | 210 | 0xc0, 0xd0, 0xe0, 0xf0, // exception flags |
michael@0 | 211 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception record |
michael@0 | 212 | 0xf9, 0xe9, 0xd9, 0xc9, 0xb9, 0xa9, 0x19, 0x09, // exception address |
michael@0 | 213 | 0x00, 0x00, 0x00, 0x00, // number parameters |
michael@0 | 214 | 0x00, 0x00, 0x00, 0x00, // __align |
michael@0 | 215 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 216 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 217 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 218 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 219 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 220 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 221 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 222 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 223 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 224 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 225 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 226 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 227 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 228 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 229 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exception_information |
michael@0 | 230 | 0xcc, 0x02, 0x00, 0x00, // context size |
michael@0 | 231 | 0x0c, 0xda, 0x65, 0x86 // context MDRVA |
michael@0 | 232 | }; |
michael@0 | 233 | EXPECT_EQ(sizeof(expected_bytes), contents.size()); |
michael@0 | 234 | EXPECT_TRUE(memcmp(contents.data(), expected_bytes, contents.size()) == 0); |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | TEST(String, Simple) { |
michael@0 | 238 | Dump dump(0, kBigEndian); |
michael@0 | 239 | String s(dump, "All mimsy were the borogoves"); |
michael@0 | 240 | string contents; |
michael@0 | 241 | ASSERT_TRUE(s.GetContents(&contents)); |
michael@0 | 242 | static const char expected[] = |
michael@0 | 243 | "\x00\x00\x00\x38\0A\0l\0l\0 \0m\0i\0m\0s\0y\0 \0w\0e\0r\0e" |
michael@0 | 244 | "\0 \0t\0h\0e\0 \0b\0o\0r\0o\0g\0o\0v\0e\0s"; |
michael@0 | 245 | string expected_string(expected, sizeof(expected) - 1); |
michael@0 | 246 | EXPECT_EQ(expected_string, contents); |
michael@0 | 247 | } |
michael@0 | 248 | |
michael@0 | 249 | TEST(String, CiteStringIn) { |
michael@0 | 250 | Dump dump(0, kLittleEndian); |
michael@0 | 251 | String s(dump, "and the mome wraths outgrabe"); |
michael@0 | 252 | Section section(dump); |
michael@0 | 253 | section.Append("initial"); |
michael@0 | 254 | s.CiteStringIn(§ion); |
michael@0 | 255 | s.Finish(0xdc2bb469); |
michael@0 | 256 | string contents; |
michael@0 | 257 | ASSERT_TRUE(section.GetContents(&contents)); |
michael@0 | 258 | EXPECT_EQ(string("initial\x69\xb4\x2b\xdc", 7 + 4), contents); |
michael@0 | 259 | } |
michael@0 | 260 | |
michael@0 | 261 | TEST(List, Empty) { |
michael@0 | 262 | Dump dump(0, kBigEndian); |
michael@0 | 263 | List<Section> list(dump, 0x2442779c); |
michael@0 | 264 | EXPECT_TRUE(list.Empty()); |
michael@0 | 265 | list.Finish(0x84e09808); |
michael@0 | 266 | string contents; |
michael@0 | 267 | ASSERT_TRUE(list.GetContents(&contents)); |
michael@0 | 268 | EXPECT_EQ(string("\0\0\0\0", 4), contents); |
michael@0 | 269 | } |
michael@0 | 270 | |
michael@0 | 271 | TEST(List, Two) { |
michael@0 | 272 | Dump dump(0, kBigEndian); |
michael@0 | 273 | List<Section> list(dump, 0x26c9f498); |
michael@0 | 274 | Section section1(dump); |
michael@0 | 275 | section1.Append("section one contents"); |
michael@0 | 276 | EXPECT_TRUE(list.Empty()); |
michael@0 | 277 | list.Add(§ion1); |
michael@0 | 278 | EXPECT_FALSE(list.Empty()); |
michael@0 | 279 | Section section2(dump); |
michael@0 | 280 | section2.Append("section two contents"); |
michael@0 | 281 | list.Add(§ion2); |
michael@0 | 282 | list.Finish(0x1e5bb60e); |
michael@0 | 283 | string contents; |
michael@0 | 284 | ASSERT_TRUE(list.GetContents(&contents)); |
michael@0 | 285 | EXPECT_EQ(string("\0\0\0\x02section one contentssection two contents", 44), |
michael@0 | 286 | contents); |
michael@0 | 287 | } |
michael@0 | 288 | |
michael@0 | 289 | TEST(Dump, Header) { |
michael@0 | 290 | Dump dump(0x9f738b33685cc84cULL, kLittleEndian, 0xb3817faf, 0x2c741c0a); |
michael@0 | 291 | dump.Finish(); |
michael@0 | 292 | string contents; |
michael@0 | 293 | ASSERT_TRUE(dump.GetContents(&contents)); |
michael@0 | 294 | ASSERT_EQ(string("\x4d\x44\x4d\x50" // signature |
michael@0 | 295 | "\xaf\x7f\x81\xb3" // version |
michael@0 | 296 | "\0\0\0\0" // stream count |
michael@0 | 297 | "\x20\0\0\0" // directory RVA (could be anything) |
michael@0 | 298 | "\0\0\0\0" // checksum |
michael@0 | 299 | "\x0a\x1c\x74\x2c" // time_date_stamp |
michael@0 | 300 | "\x4c\xc8\x5c\x68\x33\x8b\x73\x9f", // flags |
michael@0 | 301 | 32), |
michael@0 | 302 | contents); |
michael@0 | 303 | } |
michael@0 | 304 | |
michael@0 | 305 | TEST(Dump, HeaderBigEndian) { |
michael@0 | 306 | Dump dump(0x206ce3cc6fb8e0f0ULL, kBigEndian, 0x161693e2, 0x35667744); |
michael@0 | 307 | dump.Finish(); |
michael@0 | 308 | string contents; |
michael@0 | 309 | ASSERT_TRUE(dump.GetContents(&contents)); |
michael@0 | 310 | ASSERT_EQ(string("\x50\x4d\x44\x4d" // signature |
michael@0 | 311 | "\x16\x16\x93\xe2" // version |
michael@0 | 312 | "\0\0\0\0" // stream count |
michael@0 | 313 | "\0\0\0\x20" // directory RVA (could be anything) |
michael@0 | 314 | "\0\0\0\0" // checksum |
michael@0 | 315 | "\x35\x66\x77\x44" // time_date_stamp |
michael@0 | 316 | "\x20\x6c\xe3\xcc\x6f\xb8\xe0\xf0", // flags |
michael@0 | 317 | 32), |
michael@0 | 318 | contents); |
michael@0 | 319 | } |
michael@0 | 320 | |
michael@0 | 321 | TEST(Dump, OneSection) { |
michael@0 | 322 | Dump dump(0, kLittleEndian); |
michael@0 | 323 | Section section(dump); |
michael@0 | 324 | section.Append("section contents"); |
michael@0 | 325 | dump.Add(§ion); |
michael@0 | 326 | dump.Finish(); |
michael@0 | 327 | string dump_contents; |
michael@0 | 328 | // Just check for undefined labels; don't worry about the contents. |
michael@0 | 329 | ASSERT_TRUE(dump.GetContents(&dump_contents)); |
michael@0 | 330 | |
michael@0 | 331 | Section referencing_section(dump); |
michael@0 | 332 | section.CiteLocationIn(&referencing_section); |
michael@0 | 333 | string contents; |
michael@0 | 334 | ASSERT_TRUE(referencing_section.GetContents(&contents)); |
michael@0 | 335 | ASSERT_EQ(string("\x10\0\0\0\x20\0\0\0", 8), contents); |
michael@0 | 336 | } |