1ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// Copyright (c) 2006, Google Inc. 2ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// All rights reserved. 3ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// 4ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// Redistribution and use in source and binary forms, with or without 5ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// modification, are permitted provided that the following conditions are 6ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// met: 7ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// 8ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// * Redistributions of source code must retain the above copyright 9ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// notice, this list of conditions and the following disclaimer. 10ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// * Redistributions in binary form must reproduce the above 11ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// copyright notice, this list of conditions and the following disclaimer 12ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// in the documentation and/or other materials provided with the 13ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// distribution. 14ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// * Neither the name of Google Inc. nor the names of its 15ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// contributors may be used to endorse or promote products derived from 16ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// this software without specific prior written permission. 17ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// 18ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 30ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// minidump_file_writer.cc: Minidump file writer implementation. 31ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// 32ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis// See minidump_file_writer.h for documentation. 33ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 34ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis#include <fcntl.h> 35ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis#include <limits.h> 36ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis#include <stdio.h> 37ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis#include <string.h> 38ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis#include <unistd.h> 39ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 40ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis#include "client/minidump_file_writer-inl.h" 410e3b7020b8f679259acfcfdbea4d39e1c13e6f19thestig@chromium.org#include "common/linux/linux_libc_support.h" 42a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis#include "common/string_conversion.h" 43afa2f35658261c6b2a0da236138bcae6f4664811dmaclach#if defined(__linux__) && __linux__ 440e3b7020b8f679259acfcfdbea4d39e1c13e6f19thestig@chromium.org#include "third_party/lss/linux_syscall_support.h" 458d1130a89e7cdffbc0cf40230c75a9d605176377thestig@chromium.org#endif 46ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 47e5dc60822e5938fea2ae892ccddb906641ba174emmentovainamespace google_breakpad { 48ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 49a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisconst MDRVA MinidumpFileWriter::kInvalidMDRVA = static_cast<MDRVA>(-1); 50a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis 51e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.orgMinidumpFileWriter::MinidumpFileWriter() 52e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org : file_(-1), 53e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org close_file_when_destroyed_(true), 54e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org position_(0), 55e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org size_(0) { 56ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 57ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 58ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonisMinidumpFileWriter::~MinidumpFileWriter() { 59e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org if (close_file_when_destroyed_) 60e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org Close(); 61ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 62ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 63a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::Open(const char *path) { 64ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(file_ == -1); 65afa2f35658261c6b2a0da236138bcae6f4664811dmaclach#if defined(__linux__) && __linux__ 66b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid file_ = sys_open(path, O_WRONLY | O_CREAT | O_EXCL, 0600); 67b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid#else 68b62d01462c23676335eb09c0e0b988967d67b387ted.mielczarek file_ = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600); 69b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid#endif 70ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 71ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return file_ != -1; 72ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 73ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 74e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.orgvoid MinidumpFileWriter::SetFile(const int file) { 75e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org assert(file_ == -1); 76e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org file_ = file; 77e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org close_file_when_destroyed_ = false; 78e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org} 79e751dcaed67b71fa950d1f2c54cd0ddc365248f8jcivelli@chromium.org 80ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonisbool MinidumpFileWriter::Close() { 81ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis bool result = true; 82ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 83ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (file_ != -1) { 84d5b689e7af360245691e1801196d912e8774408fnealsid if (-1 == ftruncate(file_, position_)) { 85d5b689e7af360245691e1801196d912e8774408fnealsid return false; 86d5b689e7af360245691e1801196d912e8774408fnealsid } 87afa2f35658261c6b2a0da236138bcae6f4664811dmaclach#if defined(__linux__) && __linux__ 88b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid result = (sys_close(file_) == 0); 89b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid#else 90a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis result = (close(file_) == 0); 91b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid#endif 92ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis file_ = -1; 93ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } 94ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 95ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return result; 96ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 97ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 98a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::CopyStringToMDString(const wchar_t *str, 99a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis unsigned int length, 100a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis TypedMDRVA<MDString> *mdstring) { 101ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis bool result = true; 1026162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (sizeof(wchar_t) == sizeof(uint16_t)) { 103ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Shortcut if wchar_t is the same size as MDString's buffer 104a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis result = mdstring->Copy(str, mdstring->get()->length); 105ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } else { 1066162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t out[2]; 107a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis int out_idx = 0; 108b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach 109ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Copy the string character by character 110a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis while (length && result) { 111a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis UTF32ToUTF16Char(*str, out); 112a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis if (!out[0]) 113a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis return false; 114b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach 115a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // Process one character at a time 116a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis --length; 117a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis ++str; 118b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach 119a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // Append the one or two UTF-16 characters. The first one will be non- 120a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // zero, but the second one may be zero, depending on the conversion from 121a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // UTF-32. 122a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis int out_count = out[1] ? 2 : 1; 1236162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com size_t out_size = sizeof(uint16_t) * out_count; 124a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis result = mdstring->CopyIndexAfterObject(out_idx, out, out_size); 125a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis out_idx += out_count; 126ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } 127ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } 128a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis return result; 129a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis} 130ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 131a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::CopyStringToMDString(const char *str, 132a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis unsigned int length, 133a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis TypedMDRVA<MDString> *mdstring) { 134a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis bool result = true; 1356162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t out[2]; 136a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis int out_idx = 0; 137ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 138a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // Copy the string character by character 139a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis while (length && result) { 140a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis int conversion_count = UTF8ToUTF16Char(str, length, out); 141a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis if (!conversion_count) 142a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis return false; 143b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach 144a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // Move the pointer along based on the nubmer of converted characters 145a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis length -= conversion_count; 146a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis str += conversion_count; 147b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach 148a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // Append the one or two UTF-16 characters 149a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis int out_count = out[1] ? 2 : 1; 1506162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com size_t out_size = sizeof(uint16_t) * out_count; 151a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis result = mdstring->CopyIndexAfterObject(out_idx, out, out_size); 152a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis out_idx += out_count; 153ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } 154ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return result; 155ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 156ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 157a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonistemplate <typename CharType> 158a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::WriteStringCore(const CharType *str, 159a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis unsigned int length, 160a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis MDLocationDescriptor *location) { 161ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(str); 162ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(location); 163ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Calculate the mdstring length by either limiting to |length| as passed in 164ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // or by finding the location of the NULL character. 165a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis unsigned int mdstring_length = 0; 166ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (!length) 167ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis length = INT_MAX; 168a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis for (; mdstring_length < length && str[mdstring_length]; ++mdstring_length) 169a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis ; 170ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 171ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Allocate the string buffer 172ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis TypedMDRVA<MDString> mdstring(this); 1736162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com if (!mdstring.AllocateObjectAndArray(mdstring_length + 1, sizeof(uint16_t))) 174ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return false; 175ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 176a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis // Set length excluding the NULL and copy the string 177b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach mdstring.get()->length = 1786162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com static_cast<uint32_t>(mdstring_length * sizeof(uint16_t)); 179a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis bool result = CopyStringToMDString(str, mdstring_length, &mdstring); 180ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 181ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // NULL terminate 182ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (result) { 1836162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com uint16_t ch = 0; 184ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis result = mdstring.CopyIndexAfterObject(mdstring_length, &ch, sizeof(ch)); 185ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 186ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (result) 187ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis *location = mdstring.location(); 188ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } 189ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 190ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return result; 191ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 192ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 193a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::WriteString(const wchar_t *str, unsigned int length, 194a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis MDLocationDescriptor *location) { 195a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis return WriteStringCore(str, length, location); 196a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis} 197a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis 198a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::WriteString(const char *str, unsigned int length, 199a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis MDLocationDescriptor *location) { 200a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis return WriteStringCore(str, length, location); 201a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis} 202a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonis 203ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonisbool MinidumpFileWriter::WriteMemory(const void *src, size_t size, 204ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis MDMemoryDescriptor *output) { 205ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(src); 206ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(output); 207ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis UntypedMDRVA mem(this); 208ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 209ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (!mem.Allocate(size)) 210ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return false; 211ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (!mem.Copy(src, mem.size())) 212ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return false; 213ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 2146162aed3c3fcfc53373c963ac375d39a5dfa5a25ted.mielczarek@gmail.com output->start_of_memory_range = reinterpret_cast<uint64_t>(src); 215ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis output->memory = mem.location(); 216ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 217ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return true; 218ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 219ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 220ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonisMDRVA MinidumpFileWriter::Allocate(size_t size) { 221ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(size); 222ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(file_ != -1); 223ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis size_t aligned_size = (size + 7) & ~7; // 64-bit alignment 224ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 225ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (position_ + aligned_size > size_) { 226ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis size_t growth = aligned_size; 227ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis size_t minimal_growth = getpagesize(); 228ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 229ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Ensure that the file grows by at least the size of a memory page 230ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (growth < minimal_growth) 231ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis growth = minimal_growth; 232ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 233ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis size_t new_size = size_ + growth; 234ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis if (ftruncate(file_, new_size) != 0) 235ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return kInvalidMDRVA; 236ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 237ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis size_ = new_size; 238ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis } 239ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 240ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis MDRVA current_position = position_; 241ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis position_ += static_cast<MDRVA>(aligned_size); 242ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 243ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return current_position; 244ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 245ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 246a2fa3dda54c9684c3d85ed116ea8b916a8fe210ewaylonisbool MinidumpFileWriter::Copy(MDRVA position, const void *src, ssize_t size) { 2479e586c173e758b0273b1c239290b2388a4339900waylonis assert(src); 2489e586c173e758b0273b1c239290b2388a4339900waylonis assert(size); 249ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis assert(file_ != -1); 250ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 251ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Ensure that the data will fit in the allocated space 2524ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach if (static_cast<size_t>(size + position) > size_) 253ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return false; 254ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 255ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis // Seek and write the data 256afa2f35658261c6b2a0da236138bcae6f4664811dmaclach#if defined(__linux__) && __linux__ 257b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach if (sys_lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) { 258b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid if (sys_write(file_, src, size) == size) { 259b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid#else 260b5b8051a23774eed5fd38518d7a2a85736efc0bcdmaclach if (lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) { 261b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid if (write(file_, src, size) == size) { 262b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid#endif 263ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return true; 264b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid } 265b0baafc4da1f3ffb84e267dd19d176db3de1c14enealsid } 266ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 267ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis return false; 268ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis} 269ff480d4b4b59ef2182e4fd9a6874da078e8466b5waylonis 2709e586c173e758b0273b1c239290b2388a4339900waylonisbool UntypedMDRVA::Allocate(size_t size) { 2719e586c173e758b0273b1c239290b2388a4339900waylonis assert(size_ == 0); 2729e586c173e758b0273b1c239290b2388a4339900waylonis size_ = size; 2739e586c173e758b0273b1c239290b2388a4339900waylonis position_ = writer_->Allocate(size_); 2749e586c173e758b0273b1c239290b2388a4339900waylonis return position_ != MinidumpFileWriter::kInvalidMDRVA; 2759e586c173e758b0273b1c239290b2388a4339900waylonis} 2769e586c173e758b0273b1c239290b2388a4339900waylonis 2774ac61acb3a7dad6ce722fe07564be8ec92713228dmaclachbool UntypedMDRVA::Copy(MDRVA pos, const void *src, size_t size) { 2789e586c173e758b0273b1c239290b2388a4339900waylonis assert(src); 2799e586c173e758b0273b1c239290b2388a4339900waylonis assert(size); 2804ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach assert(pos + size <= position_ + size_); 2814ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach return writer_->Copy(pos, src, size); 2829e586c173e758b0273b1c239290b2388a4339900waylonis} 2839e586c173e758b0273b1c239290b2388a4339900waylonis 284e5dc60822e5938fea2ae892ccddb906641ba174emmentovai} // namespace google_breakpad 285