chromium/third_party/breakpad/breakpad/src/processor/minidump.cc

// Copyright 2010 Google LLC
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google LLC nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// minidump.cc: A minidump reader.
//
// See minidump.h for documentation.
//
// Author: Mark Mentovai

// For <inttypes.h> PRI* macros, before anything else might #include it.
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif  /* __STDC_FORMAT_MACROS */

#ifdef HAVE_CONFIG_H
#include <config.h>  // Must come first
#endif

#include "google_breakpad/processor/minidump.h"

#include <assert.h>
#include <cstdint>
#include <fcntl.h>
#include <inttypes.h>
#include <stddef.h>
#include <string.h>
#include <time.h>

#ifdef _WIN32
#include <io.h>
#else  // _WIN32
#include <unistd.h>
#endif  // _WIN32

#include <algorithm>
#include <fstream>
#include <limits>
#include <utility>

#include "processor/range_map-inl.h"

#include "common/macros.h"
#include "common/scoped_ptr.h"
#include "common/stdio_wrapper.h"
#include "google_breakpad/processor/dump_context.h"
#include "processor/basic_code_module.h"
#include "processor/basic_code_modules.h"
#include "processor/convert_old_arm64_context.h"
#include "processor/logging.h"

namespace google_breakpad {

istream;
ifstream;
numeric_limits;
vector;

namespace {

// Limit arrived at by adding up possible states in Intel Ch. 13.5 X-SAVE
// MANAGED STATE
// (~ 3680 bytes) plus some extra for the future.
const uint32_t kMaxXSaveAreaSize =;

// Returns true iff |context_size| matches exactly one of the sizes of the
// various MDRawContext* types.
// TODO(blundell): This function can be removed once
// https://bugs.chromium.org/p/google-breakpad/issues/detail?id=550 is fixed.
bool IsContextSizeUnique(uint32_t context_size) {}

//
// Swapping routines
//
// Inlining these doesn't increase code size significantly, and it saves
// a whole lot of unnecessary jumping back and forth.
//


// Swapping an 8-bit quantity is a no-op.  This function is only provided
// to account for certain templatized operations that require swapping for
// wider types but handle uint8_t too
// (MinidumpMemoryRegion::GetMemoryAtAddressInternal).
inline void Swap(uint8_t* value) {}

// Optimization: don't need to AND the furthest right shift, because we're
// shifting an unsigned quantity.  The standard requires zero-filling in this
// case.  If the quantities were signed, a bitmask whould be needed for this
// right shift to avoid an arithmetic shift (which retains the sign bit).
// The furthest left shift never needs to be ANDed bitmask.

inline void Swap(uint16_t* value) {}

inline void Swap(uint32_t* value) {}

inline void Swap(uint64_t* value) {}


// Given a pointer to a 128-bit int in the minidump data, set the "low"
// and "high" fields appropriately.
void Normalize128(uint128_struct* value, bool is_big_endian) {}

// This just swaps each int64 half of the 128-bit value.
// The value should also be normalized by calling Normalize128().
void Swap(uint128_struct* value) {}

// Swapping signed integers
inline void Swap(int32_t* value) {}

inline void Swap(MDLocationDescriptor* location_descriptor) {}

inline void Swap(MDMemoryDescriptor* memory_descriptor) {}

inline void Swap(MDGUID* guid) {}

inline void Swap(MDSystemTime* system_time) {}

inline void Swap(MDXStateFeature* xstate_feature) {}

inline void Swap(MDXStateConfigFeatureMscInfo* xstate_feature_info) {}

inline void Swap(MDRawSimpleStringDictionaryEntry* entry) {}

inline void Swap(MDRawCrashpadAnnotation* annotation) {}

inline void Swap(uint16_t* data, size_t size_in_bytes) {}

//
// Character conversion routines
//


// Standard wide-character conversion routines depend on the system's own
// idea of what width a wide character should be: some use 16 bits, and
// some use 32 bits.  For the purposes of a minidump, wide strings are
// always represented with 16-bit UTF-16 chracters.  iconv isn't available
// everywhere, and its interface varies where it is available.  iconv also
// deals purely with char* pointers, so in addition to considering the swap
// parameter, a converter that uses iconv would also need to take the host
// CPU's endianness into consideration.  It doesn't seems worth the trouble
// of making it a dependency when we don't care about anything but UTF-16.
string* UTF16ToUTF8(const vector<uint16_t>& in, bool swap) {}

// Return the smaller of the number of code units in the UTF-16 string,
// not including the terminating null word, or maxlen.
size_t UTF16codeunits(const uint16_t* string, size_t maxlen) {}

inline void Swap(MDTimeZoneInformation* time_zone) {}

void ConvertUTF16BufferToUTF8String(const uint16_t* utf16_data,
                                    size_t max_length_in_bytes,
                                    string* utf8_result,
                                    bool swap) {}


// For fields that may or may not be valid, PrintValueOrInvalid will print the
// string "(invalid)" if the field is not valid, and will print the value if
// the field is valid. The value is printed as hexadecimal or decimal.

enum NumberFormat {};

void PrintValueOrInvalid(bool valid,
                         NumberFormat number_format,
                         uint32_t value) {}

// Converts a time_t to a string showing the time in UTC.
string TimeTToUTCString(time_t tt) {}

string MDGUIDToString(const MDGUID& uuid) {}

bool IsDevAshmem(const string& filename) {}

}  // namespace

//
// MinidumpObject
//


MinidumpObject::MinidumpObject(Minidump* minidump)
    :{}


//
// MinidumpStream
//


MinidumpStream::MinidumpStream(Minidump* minidump)
    :{}


//
// MinidumpContext
//


MinidumpContext::MinidumpContext(Minidump* minidump)
    :{}

MinidumpContext::~MinidumpContext() {}

bool MinidumpContext::Read(uint32_t expected_size) {}

bool MinidumpContext::CheckAgainstSystemInfo(uint32_t context_cpu_type) {}


//
// MinidumpMemoryRegion
//


uint32_t MinidumpMemoryRegion::max_bytes_ =;  // 64MB


MinidumpMemoryRegion::MinidumpMemoryRegion(Minidump* minidump)
    :{}


MinidumpMemoryRegion::~MinidumpMemoryRegion() {}


void MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) {}


const uint8_t* MinidumpMemoryRegion::GetMemory() const {}


uint64_t MinidumpMemoryRegion::GetBase() const {}


uint32_t MinidumpMemoryRegion::GetSize() const {}


void MinidumpMemoryRegion::FreeMemory() {}


template<typename T>
bool MinidumpMemoryRegion::GetMemoryAtAddressInternal(uint64_t address,
                                                      T*        value) const {}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint8_t*  value) const {}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint16_t* value) const {}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint32_t* value) const {}


bool MinidumpMemoryRegion::GetMemoryAtAddress(uint64_t  address,
                                              uint64_t* value) const {}


void MinidumpMemoryRegion::Print() const {}


void MinidumpMemoryRegion::SetPrintMode(bool hexdump,
                                        unsigned int hexdump_width) {}


//
// MinidumpThread
//


MinidumpThread::MinidumpThread(Minidump* minidump)
    :{}


MinidumpThread::~MinidumpThread() {}


bool MinidumpThread::Read() {}

uint64_t MinidumpThread::GetStartOfStackMemoryRange() const {}

MinidumpMemoryRegion* MinidumpThread::GetMemory() {}


MinidumpContext* MinidumpThread::GetContext() {}


bool MinidumpThread::GetThreadID(uint32_t* thread_id) const {}


void MinidumpThread::Print() {}


//
// MinidumpThreadList
//


uint32_t MinidumpThreadList::max_threads_ =;


MinidumpThreadList::MinidumpThreadList(Minidump* minidump)
    :{}


MinidumpThreadList::~MinidumpThreadList() {}


bool MinidumpThreadList::Read(uint32_t expected_size) {}


MinidumpThread* MinidumpThreadList::GetThreadAtIndex(unsigned int index)
    const {}


MinidumpThread* MinidumpThreadList::GetThreadByID(uint32_t thread_id) {}


void MinidumpThreadList::Print() {}

//
// MinidumpThreadName
//

MinidumpThreadName::MinidumpThreadName(Minidump* minidump)
    :{}

MinidumpThreadName::~MinidumpThreadName() {}

bool MinidumpThreadName::Read() {}

bool MinidumpThreadName::ReadAuxiliaryData() {}

bool MinidumpThreadName::GetThreadID(uint32_t* thread_id) const {}

string MinidumpThreadName::GetThreadName() const {}

void MinidumpThreadName::Print() {}

//
// MinidumpThreadNameList
//

MinidumpThreadNameList::MinidumpThreadNameList(Minidump* minidump)
    :{}

MinidumpThreadNameList::~MinidumpThreadNameList() {}

bool MinidumpThreadNameList::Read(uint32_t expected_size) {}

MinidumpThreadName* MinidumpThreadNameList::GetThreadNameAtIndex(
    unsigned int index) const {}

void MinidumpThreadNameList::Print() {}

//
// MinidumpModule
//


uint32_t MinidumpModule::max_cv_bytes_ =;
uint32_t MinidumpModule::max_misc_bytes_ =;


MinidumpModule::MinidumpModule(Minidump* minidump)
    :{}


MinidumpModule::~MinidumpModule() {}


bool MinidumpModule::Read() {}


bool MinidumpModule::ReadAuxiliaryData() {}


string MinidumpModule::code_file() const {}


string MinidumpModule::code_identifier() const {}


string MinidumpModule::debug_file() const {}

static string guid_and_age_to_debug_id(const MDGUID& guid,
                                       uint32_t age) {}

string MinidumpModule::debug_identifier() const {}


string MinidumpModule::version() const {}


CodeModule* MinidumpModule::Copy() const {}


uint64_t MinidumpModule::shrink_down_delta() const {}

void MinidumpModule::SetShrinkDownDelta(uint64_t shrink_down_delta) {}


const uint8_t* MinidumpModule::GetCVRecord(uint32_t* size) {}


const MDImageDebugMisc* MinidumpModule::GetMiscRecord(uint32_t* size) {}


void MinidumpModule::Print() {}


//
// MinidumpModuleList
//


uint32_t MinidumpModuleList::max_modules_ =;


MinidumpModuleList::MinidumpModuleList(Minidump* minidump)
    :{}


MinidumpModuleList::~MinidumpModuleList() {}


bool MinidumpModuleList::Read(uint32_t expected_size) {}

bool MinidumpModuleList::StoreRange(const MinidumpModule& module,
                                    uint64_t base_address,
                                    uint32_t module_index,
                                    uint32_t module_count,
                                    bool is_android) {}

const MinidumpModule* MinidumpModuleList::GetModuleForAddress(
    uint64_t address) const {}


const MinidumpModule* MinidumpModuleList::GetMainModule() const {}


const MinidumpModule* MinidumpModuleList::GetModuleAtSequence(
    unsigned int sequence) const {}


const MinidumpModule* MinidumpModuleList::GetModuleAtIndex(
    unsigned int index) const {}


const CodeModules* MinidumpModuleList::Copy() const {}

vector<linked_ptr<const CodeModule> >
MinidumpModuleList::GetShrunkRangeModules() const {}

void MinidumpModuleList::Print() {}


//
// MinidumpMemoryList
//


uint32_t MinidumpMemoryList::max_regions_ =;


MinidumpMemoryList::MinidumpMemoryList(Minidump* minidump)
    :{}


MinidumpMemoryList::~MinidumpMemoryList() {}


bool MinidumpMemoryList::Read(uint32_t expected_size) {}


MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionAtIndex(
      unsigned int index) {}


MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress(
    uint64_t address) {}


void MinidumpMemoryList::Print() {}


//
// MinidumpException
//


MinidumpException::MinidumpException(Minidump* minidump)
    :{}


MinidumpException::~MinidumpException() {}


bool MinidumpException::Read(uint32_t expected_size) {}


bool MinidumpException::GetThreadID(uint32_t* thread_id) const {}


MinidumpContext* MinidumpException::GetContext() {}


void MinidumpException::Print() {}

//
// MinidumpAssertion
//


MinidumpAssertion::MinidumpAssertion(Minidump* minidump)
    :{}


MinidumpAssertion::~MinidumpAssertion() {}


bool MinidumpAssertion::Read(uint32_t expected_size) {}

void MinidumpAssertion::Print() {}

//
// MinidumpSystemInfo
//


MinidumpSystemInfo::MinidumpSystemInfo(Minidump* minidump)
    :{}


MinidumpSystemInfo::~MinidumpSystemInfo() {}


bool MinidumpSystemInfo::Read(uint32_t expected_size) {}


string MinidumpSystemInfo::GetOS() {}


string MinidumpSystemInfo::GetCPU() {}


const string* MinidumpSystemInfo::GetCSDVersion() {}


const string* MinidumpSystemInfo::GetCPUVendor() {}


void MinidumpSystemInfo::Print() {}


//
// MinidumpUnloadedModule
//


MinidumpUnloadedModule::MinidumpUnloadedModule(Minidump* minidump)
    :{}

MinidumpUnloadedModule::~MinidumpUnloadedModule() {}

string MinidumpUnloadedModule::code_file() const {}

string MinidumpUnloadedModule::code_identifier() const {}

string MinidumpUnloadedModule::debug_file() const {}

string MinidumpUnloadedModule::debug_identifier() const {}

string MinidumpUnloadedModule::version() const {}

CodeModule* MinidumpUnloadedModule::Copy() const {}

uint64_t MinidumpUnloadedModule::shrink_down_delta() const {}

void MinidumpUnloadedModule::SetShrinkDownDelta(uint64_t shrink_down_delta) {}

bool MinidumpUnloadedModule::Read(uint32_t expected_size) {}

bool MinidumpUnloadedModule::ReadAuxiliaryData() {}

//
// MinidumpUnloadedModuleList
//


uint32_t MinidumpUnloadedModuleList::max_modules_ =;


MinidumpUnloadedModuleList::MinidumpUnloadedModuleList(Minidump* minidump)
  :{}

MinidumpUnloadedModuleList::~MinidumpUnloadedModuleList() {}


bool MinidumpUnloadedModuleList::Read(uint32_t expected_size) {}

const MinidumpUnloadedModule* MinidumpUnloadedModuleList::GetModuleForAddress(
    uint64_t address) const {}

const MinidumpUnloadedModule*
MinidumpUnloadedModuleList::GetMainModule() const {}

const MinidumpUnloadedModule*
MinidumpUnloadedModuleList::GetModuleAtSequence(unsigned int sequence) const {}

const MinidumpUnloadedModule*
MinidumpUnloadedModuleList::GetModuleAtIndex(
    unsigned int index) const {}

const CodeModules* MinidumpUnloadedModuleList::Copy() const {}

vector<linked_ptr<const CodeModule>>
MinidumpUnloadedModuleList::GetShrunkRangeModules() const {}


//
// MinidumpMiscInfo
//


MinidumpMiscInfo::MinidumpMiscInfo(Minidump* minidump)
    :{}


bool MinidumpMiscInfo::Read(uint32_t expected_size) {}


void MinidumpMiscInfo::Print() {}


//
// MinidumpBreakpadInfo
//


MinidumpBreakpadInfo::MinidumpBreakpadInfo(Minidump* minidump)
    :{}


bool MinidumpBreakpadInfo::Read(uint32_t expected_size) {}


bool MinidumpBreakpadInfo::GetDumpThreadID(uint32_t* thread_id) const {}


bool MinidumpBreakpadInfo::GetRequestingThreadID(uint32_t* thread_id)
    const {}


void MinidumpBreakpadInfo::Print() {}


//
// MinidumpMemoryInfo
//


MinidumpMemoryInfo::MinidumpMemoryInfo(Minidump* minidump)
    :{}


bool MinidumpMemoryInfo::IsExecutable() const {}


bool MinidumpMemoryInfo::IsWritable() const {}


bool MinidumpMemoryInfo::Read() {}


void MinidumpMemoryInfo::Print() {}


//
// MinidumpMemoryInfoList
//


MinidumpMemoryInfoList::MinidumpMemoryInfoList(Minidump* minidump)
    :{}


MinidumpMemoryInfoList::~MinidumpMemoryInfoList() {}


bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {}


const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoAtIndex(
      unsigned int index) const {}


const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress(
    uint64_t address) const {}


void MinidumpMemoryInfoList::Print() {}

//
// MinidumpLinuxMaps
//

MinidumpLinuxMaps::MinidumpLinuxMaps(Minidump* minidump)
    :{}

void MinidumpLinuxMaps::Print() const {}

//
// MinidumpLinuxMapsList
//

MinidumpLinuxMapsList::MinidumpLinuxMapsList(Minidump* minidump)
    :{}

MinidumpLinuxMapsList::~MinidumpLinuxMapsList() {}

const MinidumpLinuxMaps* MinidumpLinuxMapsList::GetLinuxMapsForAddress(
    uint64_t address) const {}

const MinidumpLinuxMaps* MinidumpLinuxMapsList::GetLinuxMapsAtIndex(
    unsigned int index) const {}

bool MinidumpLinuxMapsList::Read(uint32_t expected_size) {}

void MinidumpLinuxMapsList::Print() const {}

//
// MinidumpCrashpadInfo
//


MinidumpCrashpadInfo::MinidumpCrashpadInfo(Minidump* minidump)
    :{}


bool MinidumpCrashpadInfo::Read(uint32_t expected_size) {}


void MinidumpCrashpadInfo::Print() {}


//
// Minidump
//


uint32_t Minidump::max_streams_ =;
unsigned int Minidump::max_string_length_ =;


Minidump::Minidump(const string& path, bool hexdump, unsigned int hexdump_width)
    :{}

Minidump::Minidump(istream& stream)
    :{}

Minidump::~Minidump() {}


bool Minidump::Open() {}

bool Minidump::GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags) {}


bool Minidump::Read() {}


MinidumpThreadList* Minidump::GetThreadList() {}

MinidumpThreadNameList* Minidump::GetThreadNameList() {}

MinidumpModuleList* Minidump::GetModuleList() {}


MinidumpMemoryList* Minidump::GetMemoryList() {}


MinidumpException* Minidump::GetException() {}

MinidumpAssertion* Minidump::GetAssertion() {}


MinidumpSystemInfo* Minidump::GetSystemInfo() {}


MinidumpUnloadedModuleList* Minidump::GetUnloadedModuleList() {}


MinidumpMiscInfo* Minidump::GetMiscInfo() {}


MinidumpBreakpadInfo* Minidump::GetBreakpadInfo() {}

MinidumpMemoryInfoList* Minidump::GetMemoryInfoList() {}

MinidumpLinuxMapsList* Minidump::GetLinuxMapsList() {}

bool Minidump::IsAndroid() {}

bool Minidump::GetPlatform(MDOSPlatform* platform) {}

MinidumpCrashpadInfo* Minidump::GetCrashpadInfo() {}

static const char* get_stream_name(uint32_t stream_type) {}

void Minidump::Print() {}


const MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index)
      const {}


bool Minidump::ReadBytes(void* bytes, size_t count) {}


bool Minidump::SeekSet(off_t offset) {}

off_t Minidump::Tell() {}


string* Minidump::ReadString(off_t offset) {}


bool Minidump::ReadUTF8String(off_t offset, string* string_utf8) {}


bool Minidump::ReadStringList(
    off_t offset,
    std::vector<std::string>* string_list) {}


bool Minidump::ReadSimpleStringDictionary(
    off_t offset,
    std::map<std::string, std::string>* simple_string_dictionary) {}

bool Minidump::ReadCrashpadAnnotationsList(
    off_t offset,
    std::vector<MinidumpCrashpadInfo::AnnotationObject>* annotations_list) {}

bool Minidump::SeekToStreamType(uint32_t  stream_type,
                                uint32_t* stream_length) {}


template<typename T>
T* Minidump::GetStream(T** stream) {}

}  // namespace google_breakpad