toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/synth_minidump.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,352 @@
     1.4 +// Copyright (c) 2010, Google Inc.
     1.5 +// All rights reserved.
     1.6 +//
     1.7 +// Redistribution and use in source and binary forms, with or without
     1.8 +// modification, are permitted provided that the following conditions are
     1.9 +// met:
    1.10 +//
    1.11 +//     * Redistributions of source code must retain the above copyright
    1.12 +// notice, this list of conditions and the following disclaimer.
    1.13 +//     * Redistributions in binary form must reproduce the above
    1.14 +// copyright notice, this list of conditions and the following disclaimer
    1.15 +// in the documentation and/or other materials provided with the
    1.16 +// distribution.
    1.17 +//     * Neither the name of Google Inc. nor the names of its
    1.18 +// contributors may be used to endorse or promote products derived from
    1.19 +// this software without specific prior written permission.
    1.20 +//
    1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    1.32 +
    1.33 +// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
    1.34 +
    1.35 +// synth_minidump.cc: Implementation of SynthMinidump.  See synth_minidump.h
    1.36 +
    1.37 +#include "processor/synth_minidump.h"
    1.38 +
    1.39 +namespace google_breakpad {
    1.40 +
    1.41 +namespace SynthMinidump {
    1.42 +
    1.43 +Section::Section(const Dump &dump)
    1.44 +  : test_assembler::Section(dump.endianness()) { }
    1.45 +
    1.46 +void Section::CiteLocationIn(test_assembler::Section *section) const {
    1.47 +  if (this)
    1.48 +    (*section).D32(size_).D32(file_offset_);
    1.49 +  else
    1.50 +    (*section).D32(0).D32(0);
    1.51 +}
    1.52 +
    1.53 +void Stream::CiteStreamIn(test_assembler::Section *section) const {
    1.54 +  section->D32(type_);
    1.55 +  CiteLocationIn(section);
    1.56 +}
    1.57 +
    1.58 +SystemInfo::SystemInfo(const Dump &dump,
    1.59 +                       const MDRawSystemInfo &system_info,
    1.60 +                       const String &csd_version)
    1.61 +    : Stream(dump, MD_SYSTEM_INFO_STREAM) {
    1.62 +  D16(system_info.processor_architecture);
    1.63 +  D16(system_info.processor_level);
    1.64 +  D16(system_info.processor_revision);
    1.65 +  D8(system_info.number_of_processors);
    1.66 +  D8(system_info.product_type);
    1.67 +  D32(system_info.major_version);
    1.68 +  D32(system_info.minor_version);
    1.69 +  D32(system_info.build_number);
    1.70 +  D32(system_info.platform_id);
    1.71 +  csd_version.CiteStringIn(this);
    1.72 +  D16(system_info.suite_mask);
    1.73 +  D16(system_info.reserved2);           // Well, why not?
    1.74 +
    1.75 +  // MDCPUInformation cpu;
    1.76 +  if (system_info.processor_architecture == MD_CPU_ARCHITECTURE_X86) {
    1.77 +    D32(system_info.cpu.x86_cpu_info.vendor_id[0]);
    1.78 +    D32(system_info.cpu.x86_cpu_info.vendor_id[1]);
    1.79 +    D32(system_info.cpu.x86_cpu_info.vendor_id[2]);
    1.80 +    D32(system_info.cpu.x86_cpu_info.version_information);
    1.81 +    D32(system_info.cpu.x86_cpu_info.feature_information);
    1.82 +    D32(system_info.cpu.x86_cpu_info.amd_extended_cpu_features);
    1.83 +  } else {
    1.84 +    D64(system_info.cpu.other_cpu_info.processor_features[0]);
    1.85 +    D64(system_info.cpu.other_cpu_info.processor_features[1]);
    1.86 +  }
    1.87 +}
    1.88 +
    1.89 +const MDRawSystemInfo SystemInfo::windows_x86 = {
    1.90 +  MD_CPU_ARCHITECTURE_X86,              // processor_architecture
    1.91 +  6,                                    // processor_level
    1.92 +  0xd08,                                // processor_revision
    1.93 +  1,                                    // number_of_processors
    1.94 +  1,                                    // product_type
    1.95 +  5,                                    // major_version
    1.96 +  1,                                    // minor_version
    1.97 +  2600,                                 // build_number
    1.98 +  2,                                    // platform_id
    1.99 +  0xdeadbeef,                           // csd_version_rva
   1.100 +  0x100,                                // suite_mask
   1.101 +  0,                                    // reserved2
   1.102 +  {                                     // cpu
   1.103 +    { // x86_cpu_info
   1.104 +      { 0x756e6547, 0x49656e69, 0x6c65746e }, // vendor_id
   1.105 +      0x6d8,                                  // version_information
   1.106 +      0xafe9fbff,                             // feature_information
   1.107 +      0xffffffff                              // amd_extended_cpu_features
   1.108 +    }
   1.109 +  }
   1.110 +};
   1.111 +
   1.112 +const string SystemInfo::windows_x86_csd_version = "Service Pack 2";
   1.113 +
   1.114 +String::String(const Dump &dump, const string &contents) : Section(dump) {
   1.115 +  D32(contents.size() * 2);
   1.116 +  for (string::const_iterator i = contents.begin(); i != contents.end(); i++)
   1.117 +    D16(*i);
   1.118 +}
   1.119 +
   1.120 +void String::CiteStringIn(test_assembler::Section *section) const {
   1.121 +  section->D32(file_offset_);
   1.122 +}
   1.123 +
   1.124 +void Memory::CiteMemoryIn(test_assembler::Section *section) const {
   1.125 +  section->D64(address_);
   1.126 +  CiteLocationIn(section);
   1.127 +}
   1.128 +
   1.129 +Context::Context(const Dump &dump, const MDRawContextX86 &context)
   1.130 +  : Section(dump) {
   1.131 +  // The caller should have properly set the CPU type flag.
   1.132 +  // The high 24 bits identify the CPU.  Note that context records with no CPU
   1.133 +  // type information can be valid (e.g. produced by ::RtlCaptureContext).
   1.134 +  assert(((context.context_flags & MD_CONTEXT_CPU_MASK) == 0) ||
   1.135 +         (context.context_flags & MD_CONTEXT_X86));
   1.136 +  // It doesn't make sense to store x86 registers in big-endian form.
   1.137 +  assert(dump.endianness() == kLittleEndian);
   1.138 +  D32(context.context_flags);
   1.139 +  D32(context.dr0);
   1.140 +  D32(context.dr1);
   1.141 +  D32(context.dr2);
   1.142 +  D32(context.dr3);
   1.143 +  D32(context.dr6);
   1.144 +  D32(context.dr7);
   1.145 +  D32(context.float_save.control_word);
   1.146 +  D32(context.float_save.status_word);
   1.147 +  D32(context.float_save.tag_word);
   1.148 +  D32(context.float_save.error_offset);
   1.149 +  D32(context.float_save.error_selector);
   1.150 +  D32(context.float_save.data_offset);
   1.151 +  D32(context.float_save.data_selector);
   1.152 +  // context.float_save.register_area[] contains 8-bit quantities and
   1.153 +  // does not need to be swapped.
   1.154 +  Append(context.float_save.register_area,
   1.155 +         sizeof(context.float_save.register_area));
   1.156 +  D32(context.float_save.cr0_npx_state);
   1.157 +  D32(context.gs);
   1.158 +  D32(context.fs);
   1.159 +  D32(context.es);
   1.160 +  D32(context.ds);
   1.161 +  D32(context.edi);
   1.162 +  D32(context.esi);
   1.163 +  D32(context.ebx);
   1.164 +  D32(context.edx);
   1.165 +  D32(context.ecx);
   1.166 +  D32(context.eax);
   1.167 +  D32(context.ebp);
   1.168 +  D32(context.eip);
   1.169 +  D32(context.cs);
   1.170 +  D32(context.eflags);
   1.171 +  D32(context.esp);
   1.172 +  D32(context.ss);
   1.173 +  // context.extended_registers[] contains 8-bit quantities and does
   1.174 +  // not need to be swapped.
   1.175 +  Append(context.extended_registers, sizeof(context.extended_registers));
   1.176 +  assert(Size() == sizeof(MDRawContextX86));
   1.177 +}
   1.178 +
   1.179 +Context::Context(const Dump &dump, const MDRawContextARM &context)
   1.180 +  : Section(dump) {
   1.181 +  // The caller should have properly set the CPU type flag.
   1.182 +  assert((context.context_flags & MD_CONTEXT_ARM) ||
   1.183 +         (context.context_flags & MD_CONTEXT_ARM_OLD));
   1.184 +  // It doesn't make sense to store ARM registers in big-endian form.
   1.185 +  assert(dump.endianness() == kLittleEndian);
   1.186 +  D32(context.context_flags);
   1.187 +  for (int i = 0; i < MD_CONTEXT_ARM_GPR_COUNT; ++i)
   1.188 +    D32(context.iregs[i]);
   1.189 +  D32(context.cpsr);
   1.190 +  D64(context.float_save.fpscr);
   1.191 +  for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPR_COUNT; ++i)
   1.192 +    D64(context.float_save.regs[i]);
   1.193 +  for (int i = 0; i < MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT; ++i)
   1.194 +    D32(context.float_save.extra[i]);
   1.195 +  assert(Size() == sizeof(MDRawContextARM));
   1.196 +}
   1.197 +
   1.198 +Thread::Thread(const Dump &dump,
   1.199 +               uint32_t thread_id, const Memory &stack, const Context &context,
   1.200 +               uint32_t suspend_count, uint32_t priority_class,
   1.201 +               uint32_t priority, uint64_t teb) : Section(dump) {
   1.202 +  D32(thread_id);
   1.203 +  D32(suspend_count);
   1.204 +  D32(priority_class);
   1.205 +  D32(priority);
   1.206 +  D64(teb);
   1.207 +  stack.CiteMemoryIn(this);
   1.208 +  context.CiteLocationIn(this);
   1.209 +  assert(Size() == sizeof(MDRawThread));
   1.210 +}
   1.211 +
   1.212 +Module::Module(const Dump &dump,
   1.213 +               uint64_t base_of_image,
   1.214 +               uint32_t size_of_image,
   1.215 +               const String &name,
   1.216 +               uint32_t time_date_stamp,
   1.217 +               uint32_t checksum,
   1.218 +               const MDVSFixedFileInfo &version_info,
   1.219 +               const Section *cv_record,
   1.220 +               const Section *misc_record) : Section(dump) {
   1.221 +  D64(base_of_image);
   1.222 +  D32(size_of_image);
   1.223 +  D32(checksum);
   1.224 +  D32(time_date_stamp);
   1.225 +  name.CiteStringIn(this);
   1.226 +  D32(version_info.signature);
   1.227 +  D32(version_info.struct_version);
   1.228 +  D32(version_info.file_version_hi);
   1.229 +  D32(version_info.file_version_lo);
   1.230 +  D32(version_info.product_version_hi);
   1.231 +  D32(version_info.product_version_lo);
   1.232 +  D32(version_info.file_flags_mask);
   1.233 +  D32(version_info.file_flags);
   1.234 +  D32(version_info.file_os);
   1.235 +  D32(version_info.file_type);
   1.236 +  D32(version_info.file_subtype);
   1.237 +  D32(version_info.file_date_hi);
   1.238 +  D32(version_info.file_date_lo);
   1.239 +  cv_record->CiteLocationIn(this);
   1.240 +  misc_record->CiteLocationIn(this);
   1.241 +  D64(0).D64(0);
   1.242 +}
   1.243 +
   1.244 +const MDVSFixedFileInfo Module::stock_version_info = {
   1.245 +  MD_VSFIXEDFILEINFO_SIGNATURE,         // signature
   1.246 +  MD_VSFIXEDFILEINFO_VERSION,           // struct_version
   1.247 +  0x11111111,                           // file_version_hi
   1.248 +  0x22222222,                           // file_version_lo
   1.249 +  0x33333333,                           // product_version_hi
   1.250 +  0x44444444,                           // product_version_lo
   1.251 +  MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG,  // file_flags_mask
   1.252 +  MD_VSFIXEDFILEINFO_FILE_FLAGS_DEBUG,  // file_flags
   1.253 +  MD_VSFIXEDFILEINFO_FILE_OS_NT | MD_VSFIXEDFILEINFO_FILE_OS__WINDOWS32,
   1.254 +                                        // file_os
   1.255 +  MD_VSFIXEDFILEINFO_FILE_TYPE_APP,     // file_type
   1.256 +  MD_VSFIXEDFILEINFO_FILE_SUBTYPE_UNKNOWN, // file_subtype
   1.257 +  0,                                    // file_date_hi
   1.258 +  0                                     // file_date_lo
   1.259 +};
   1.260 +
   1.261 +Exception::Exception(const Dump &dump,
   1.262 +                     const Context &context,
   1.263 +                     uint32_t thread_id,
   1.264 +                     uint32_t exception_code,
   1.265 +                     uint32_t exception_flags,
   1.266 +                     uint64_t exception_address)
   1.267 +  : Stream(dump, MD_EXCEPTION_STREAM) {
   1.268 +  D32(thread_id);
   1.269 +  D32(0);  // __align
   1.270 +  D32(exception_code);
   1.271 +  D32(exception_flags);
   1.272 +  D64(0);  // exception_record
   1.273 +  D64(exception_address);
   1.274 +  D32(0);  // number_parameters
   1.275 +  D32(0);  // __align
   1.276 +  for (int i = 0; i < MD_EXCEPTION_MAXIMUM_PARAMETERS; ++i)
   1.277 +    D64(0);  // exception_information
   1.278 +  context.CiteLocationIn(this);
   1.279 +  assert(Size() == sizeof(MDRawExceptionStream));
   1.280 +}
   1.281 +
   1.282 +Dump::Dump(uint64_t flags,
   1.283 +           Endianness endianness,
   1.284 +           uint32_t version,
   1.285 +           uint32_t date_time_stamp)
   1.286 +    : test_assembler::Section(endianness),
   1.287 +      file_start_(0),
   1.288 +      stream_directory_(*this),
   1.289 +      stream_count_(0),
   1.290 +      thread_list_(*this, MD_THREAD_LIST_STREAM),
   1.291 +      module_list_(*this, MD_MODULE_LIST_STREAM),
   1.292 +      memory_list_(*this, MD_MEMORY_LIST_STREAM)
   1.293 + {
   1.294 +  D32(MD_HEADER_SIGNATURE);
   1.295 +  D32(version);
   1.296 +  D32(stream_count_label_);
   1.297 +  D32(stream_directory_rva_);
   1.298 +  D32(0);
   1.299 +  D32(date_time_stamp);
   1.300 +  D64(flags);
   1.301 +  assert(Size() == sizeof(MDRawHeader));
   1.302 +}
   1.303 +
   1.304 +Dump &Dump::Add(SynthMinidump::Section *section) {
   1.305 +  section->Finish(file_start_ + Size());
   1.306 +  Append(*section);
   1.307 +  return *this;
   1.308 +}
   1.309 +
   1.310 +Dump &Dump::Add(Stream *stream) {
   1.311 +  Add(static_cast<SynthMinidump::Section *>(stream));
   1.312 +  stream->CiteStreamIn(&stream_directory_);
   1.313 +  stream_count_++;
   1.314 +  return *this;
   1.315 +}
   1.316 +
   1.317 +Dump &Dump::Add(Memory *memory) {
   1.318 +  // Add the memory contents themselves to the file.
   1.319 +  Add(static_cast<SynthMinidump::Section *>(memory));
   1.320 +
   1.321 +  // The memory list is a list of MDMemoryDescriptors, not of actual
   1.322 +  // memory elements. Produce a descriptor, and add that to the list.
   1.323 +  SynthMinidump::Section descriptor(*this);
   1.324 +  memory->CiteMemoryIn(&descriptor);
   1.325 +  memory_list_.Add(&descriptor);
   1.326 +  return *this;
   1.327 +}
   1.328 +
   1.329 +Dump &Dump::Add(Thread *thread) {
   1.330 +  thread_list_.Add(thread);
   1.331 +  return *this;
   1.332 +}
   1.333 +
   1.334 +Dump &Dump::Add(Module *module) {
   1.335 +  module_list_.Add(module);
   1.336 +  return *this;
   1.337 +}
   1.338 +
   1.339 +void Dump::Finish() {
   1.340 +  if (!thread_list_.Empty()) Add(&thread_list_);
   1.341 +  if (!module_list_.Empty()) Add(&module_list_);
   1.342 +  if (!memory_list_.Empty()) Add(&memory_list_);
   1.343 +
   1.344 +  // Create the stream directory. We don't use
   1.345 +  // stream_directory_.Finish here, because the stream directory isn't
   1.346 +  // cited using a location descriptor; rather, the Minidump header
   1.347 +  // has the stream count and MDRVA.
   1.348 +  stream_count_label_ = stream_count_;
   1.349 +  stream_directory_rva_ = file_start_ + Size();
   1.350 +  Append(static_cast<test_assembler::Section &>(stream_directory_));
   1.351 +}
   1.352 +
   1.353 +} // namespace SynthMinidump
   1.354 +          
   1.355 +} // namespace google_breakpad

mercurial