Adding support for 64-bit Windows modules to ms_symbol_server_converter.

As part of that:
 - Updated MSSymbolServerConverter to also download the executable files from the symbol server and pass them to the PDBSourceLineWriter as it is required for successful conversion of symbols for 64-bit modules.
 - Added a .gyp file and target for the ms_symbol_server_converter library.
 - Updated PDBSourceLineWriter to allow executable files to be in locations different from the locations of the PDB files.
 - Minor style issue:
    * #define guards.
    * No space before ')' and after '('.

R=mark@chromium.org, wfh@chromium.org

Review URL: https://breakpad.appspot.com/1434002

git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1309 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
ivan.penkov@gmail.com
2014-04-10 17:54:52 +00:00
parent 7dbca422d4
commit 6b0703a093
12 changed files with 875 additions and 687 deletions

View File

@@ -1,59 +1,64 @@
// Copyright 2013 Google Inc. All rights reserved.
//
// 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 Inc. 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.
// Utilities for loading debug streams and tables from a PDB file.
#include <Windows.h>
#include <dia2.h>
namespace google_breakpad {
// Find the debug stream of the given |name| in the given |session|. Returns
// true on success, false on error of if the stream does not exist. On success
// the stream will be returned via |debug_stream|.
bool FindDebugStream(const wchar_t* name,
IDiaSession* session,
IDiaEnumDebugStreamData** debug_stream);
// Finds the first table implementing the COM interface with ID |iid| in the
// given |session|. Returns true on success, false on error or if no such
// table is found. On success the table will be returned via |table|.
bool FindTable(REFIID iid, IDiaSession* session, void** table);
// A templated version of FindTable. Finds the first table implementing type
// |InterfaceType| in the given |session|. Returns true on success, false on
// error or if no such table is found. On success the table will be returned via
// |table|.
template<typename InterfaceType>
bool FindTable(IDiaSession* session, InterfaceType** table) {
return FindTable(__uuidof(InterfaceType),
session,
reinterpret_cast<void**>(table));
}
} // namespace google_breakpad
// Copyright 2013 Google Inc. All rights reserved.
//
// 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 Inc. 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.
// Utilities for loading debug streams and tables from a PDB file.
#ifndef COMMON_WINDOWS_DIA_UTIL_H_
#define COMMON_WINDOWS_DIA_UTIL_H_
#include <Windows.h>
#include <dia2.h>
namespace google_breakpad {
// Find the debug stream of the given |name| in the given |session|. Returns
// true on success, false on error of if the stream does not exist. On success
// the stream will be returned via |debug_stream|.
bool FindDebugStream(const wchar_t* name,
IDiaSession* session,
IDiaEnumDebugStreamData** debug_stream);
// Finds the first table implementing the COM interface with ID |iid| in the
// given |session|. Returns true on success, false on error or if no such
// table is found. On success the table will be returned via |table|.
bool FindTable(REFIID iid, IDiaSession* session, void** table);
// A templated version of FindTable. Finds the first table implementing type
// |InterfaceType| in the given |session|. Returns true on success, false on
// error or if no such table is found. On success the table will be returned via
// |table|.
template<typename InterfaceType>
bool FindTable(IDiaSession* session, InterfaceType** table) {
return FindTable(__uuidof(InterfaceType),
session,
reinterpret_cast<void**>(table));
}
} // namespace google_breakpad
#endif // COMMON_WINDOWS_DIA_UTIL_H_

View File

@@ -29,8 +29,8 @@
// guid_string.cc: Convert GUIDs to strings.
#ifndef COMMON_WINDOWS_GUID_STRING_H__
#define COMMON_WINDOWS_GUID_STRING_H__
#ifndef COMMON_WINDOWS_GUID_STRING_H_
#define COMMON_WINDOWS_GUID_STRING_H_
#include <Guiddef.h>
@@ -55,4 +55,4 @@ class GUIDString {
} // namespace google_breakpad
#endif // COMMON_WINDOWS_GUID_STRING_H__
#endif // COMMON_WINDOWS_GUID_STRING_H_

View File

@@ -31,12 +31,12 @@
// request using wininet. It currently supports requests that contain
// a set of string parameters (key/value pairs), and a file to upload.
#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H__
#define COMMON_WINDOWS_HTTP_UPLOAD_H__
#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H_
#define COMMON_WINDOWS_HTTP_UPLOAD_H_
#pragma warning( push )
#pragma warning(push)
// Disable exception handler warnings.
#pragma warning( disable : 4530 )
#pragma warning(disable : 4530)
#include <Windows.h>
#include <WinInet.h>
@@ -121,6 +121,6 @@ class HTTPUpload {
} // namespace google_breakpad
#pragma warning( pop )
#pragma warning(pop)
#endif // COMMON_WINDOWS_HTTP_UPLOAD_H__
#endif // COMMON_WINDOWS_HTTP_UPLOAD_H_

View File

@@ -1,72 +1,72 @@
// Copyright 2013 Google Inc. All rights reserved.
//
// 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 Inc. 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.
// Provides an API for mapping symbols through OMAP information, if a PDB file
// is augmented with it. This allows breakpad to work with addresses in
// transformed images by transforming the symbols themselves, rather than
// transforming addresses prior to querying symbols (the way it is typically
// done by Windows-native tools, including the DIA).
#ifndef COMMON_WINDOWS_OMAP_H__
#define COMMON_WINDOWS_OMAP_H__
#include "common/windows/omap_internal.h"
namespace google_breakpad {
// If the given session contains OMAP data this extracts it, populating
// |omap_data|, and then disabling automatic translation for the session.
// OMAP data is present in the PDB if |omap_data| is not empty. This returns
// true on success, false otherwise.
bool GetOmapDataAndDisableTranslation(IDiaSession* dia_session,
OmapData* omap_data);
// Given raw OMAP data builds an ImageMap. This can be used to query individual
// image ranges using MapAddressRange.
// |omap_data|| is the OMAP data extracted from the PDB.
// |image_map| will be populated with a description of the image mapping. If
// |omap_data| is empty then this will also be empty.
void BuildImageMap(const OmapData& omap_data, ImageMap* image_map);
// Given an address range in the original image space determines how exactly it
// has been tranformed.
// |omap_data| is the OMAP data extracted from the PDB, which must not be
// empty.
// |original_range| is the address range in the original image being queried.
// |mapped_ranges| will be populated with a full description of the mapping.
// They may be disjoint in the transformed image so a vector is needed to
// fully represent the mapping. This will be appended to if it is not
// empty. If |omap_data| is empty then |mapped_ranges| will simply be
// populated with a copy of |original_range| (the identity transform).
void MapAddressRange(const ImageMap& image_map,
const AddressRange& original_range,
AddressRangeVector* mapped_ranges);
} // namespace google_breakpad
#endif // COMMON_WINDOWS_OMAP_H__
// Copyright 2013 Google Inc. All rights reserved.
//
// 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 Inc. 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.
// Provides an API for mapping symbols through OMAP information, if a PDB file
// is augmented with it. This allows breakpad to work with addresses in
// transformed images by transforming the symbols themselves, rather than
// transforming addresses prior to querying symbols (the way it is typically
// done by Windows-native tools, including the DIA).
#ifndef COMMON_WINDOWS_OMAP_H_
#define COMMON_WINDOWS_OMAP_H_
#include "common/windows/omap_internal.h"
namespace google_breakpad {
// If the given session contains OMAP data this extracts it, populating
// |omap_data|, and then disabling automatic translation for the session.
// OMAP data is present in the PDB if |omap_data| is not empty. This returns
// true on success, false otherwise.
bool GetOmapDataAndDisableTranslation(IDiaSession* dia_session,
OmapData* omap_data);
// Given raw OMAP data builds an ImageMap. This can be used to query individual
// image ranges using MapAddressRange.
// |omap_data|| is the OMAP data extracted from the PDB.
// |image_map| will be populated with a description of the image mapping. If
// |omap_data| is empty then this will also be empty.
void BuildImageMap(const OmapData& omap_data, ImageMap* image_map);
// Given an address range in the original image space determines how exactly it
// has been tranformed.
// |omap_data| is the OMAP data extracted from the PDB, which must not be
// empty.
// |original_range| is the address range in the original image being queried.
// |mapped_ranges| will be populated with a full description of the mapping.
// They may be disjoint in the transformed image so a vector is needed to
// fully represent the mapping. This will be appended to if it is not
// empty. If |omap_data| is empty then |mapped_ranges| will simply be
// populated with a copy of |original_range| (the identity transform).
void MapAddressRange(const ImageMap& image_map,
const AddressRange& original_range,
AddressRangeVector* mapped_ranges);
} // namespace google_breakpad
#endif // COMMON_WINDOWS_OMAP_H_

View File

@@ -1,137 +1,137 @@
// Copyright 2013 Google Inc. All rights reserved.
//
// 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 Inc. 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.
// Declares internal implementation details for functionality in omap.h and
// omap.cc.
#ifndef COMMON_WINDOWS_OMAP_INTERNAL_H__
#define COMMON_WINDOWS_OMAP_INTERNAL_H__
#include <windows.h>
#include <dia2.h>
#include <vector>
namespace google_breakpad {
// The OMAP struct is defined by debughlp.h, which doesn't play nicely with
// imagehlp.h. We simply redefine it.
struct OMAP {
DWORD rva;
DWORD rvaTo;
};
static_assert(sizeof(OMAP) == 8, "Wrong size for OMAP structure.");
typedef std::vector<OMAP> OmapTable;
// This contains the OMAP data extracted from an image.
struct OmapData {
// The table of OMAP entries describing the transformation from the
// original image to the transformed image.
OmapTable omap_from;
// The table of OMAP entries describing the transformation from the
// instrumented image to the original image.
OmapTable omap_to;
// The length of the original untransformed image.
DWORD length_original;
OmapData() : length_original(0) { }
};
// This represents a range of addresses in an image.
struct AddressRange {
DWORD rva;
DWORD length;
AddressRange() : rva(0), length(0) { }
AddressRange(DWORD rva, DWORD length) : rva(rva), length(length) { }
// Returns the end address of this range.
DWORD end() const { return rva + length; }
// Addreses only compare as less-than or greater-than if they are not
// overlapping. Otherwise, they compare equal.
int Compare(const AddressRange& rhs) const;
bool operator<(const AddressRange& rhs) const { return Compare(rhs) == -1; }
bool operator>(const AddressRange& rhs) const { return Compare(rhs) == 1; }
// Equality operators compare exact values.
bool operator==(const AddressRange& rhs) const {
return rva == rhs.rva && length == rhs.length;
}
bool operator!=(const AddressRange& rhs) const { return !((*this) == rhs); }
};
typedef std::vector<AddressRange> AddressRangeVector;
// This represents an address range in an original image, and its corresponding
// range in the transformed image.
struct MappedRange {
// An address in the original image.
DWORD rva_original;
// The corresponding addresses in the transformed image.
DWORD rva_transformed;
// The length of the address range.
DWORD length;
// It is possible for code to be injected into a transformed image, for which
// there is no corresponding code in the original image. If this range of
// transformed image is immediately followed by such injected code we maintain
// a record of its length here.
DWORD injected;
// It is possible for code to be removed from the original image. This happens
// for things like padding between blocks. There is no actual content lost,
// but the spacing between items may be lost. This keeps track of any removed
// content immediately following the |original| range.
DWORD removed;
};
// A vector of mapped ranges is used as a more useful representation of
// OMAP data.
typedef std::vector<MappedRange> Mapping;
// Used as a secondary search structure accompanying a Mapping.
struct EndpointIndex {
DWORD endpoint;
size_t index;
};
typedef std::vector<EndpointIndex> EndpointIndexMap;
// An ImageMap is vector of mapped ranges, plus a secondary index into it for
// doing interval searches. (An interval tree would also work, but is overkill
// because we don't need insertion and deletion.)
struct ImageMap {
// This is a description of the mapping between original and transformed
// image, sorted by addresses in the original image.
Mapping mapping;
// For all interval endpoints in |mapping| this stores the minimum index of
// an interval in |mapping| that contains the endpoint. Useful for doing
// interval intersection queries.
EndpointIndexMap endpoint_index_map;
};
} // namespace google_breakpad
#endif // COMMON_WINDOWS_OMAP_INTERNAL_H__
// Copyright 2013 Google Inc. All rights reserved.
//
// 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 Inc. 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.
// Declares internal implementation details for functionality in omap.h and
// omap.cc.
#ifndef COMMON_WINDOWS_OMAP_INTERNAL_H_
#define COMMON_WINDOWS_OMAP_INTERNAL_H_
#include <windows.h>
#include <dia2.h>
#include <vector>
namespace google_breakpad {
// The OMAP struct is defined by debughlp.h, which doesn't play nicely with
// imagehlp.h. We simply redefine it.
struct OMAP {
DWORD rva;
DWORD rvaTo;
};
static_assert(sizeof(OMAP) == 8, "Wrong size for OMAP structure.");
typedef std::vector<OMAP> OmapTable;
// This contains the OMAP data extracted from an image.
struct OmapData {
// The table of OMAP entries describing the transformation from the
// original image to the transformed image.
OmapTable omap_from;
// The table of OMAP entries describing the transformation from the
// instrumented image to the original image.
OmapTable omap_to;
// The length of the original untransformed image.
DWORD length_original;
OmapData() : length_original(0) { }
};
// This represents a range of addresses in an image.
struct AddressRange {
DWORD rva;
DWORD length;
AddressRange() : rva(0), length(0) { }
AddressRange(DWORD rva, DWORD length) : rva(rva), length(length) { }
// Returns the end address of this range.
DWORD end() const { return rva + length; }
// Addreses only compare as less-than or greater-than if they are not
// overlapping. Otherwise, they compare equal.
int Compare(const AddressRange& rhs) const;
bool operator<(const AddressRange& rhs) const { return Compare(rhs) == -1; }
bool operator>(const AddressRange& rhs) const { return Compare(rhs) == 1; }
// Equality operators compare exact values.
bool operator==(const AddressRange& rhs) const {
return rva == rhs.rva && length == rhs.length;
}
bool operator!=(const AddressRange& rhs) const { return !((*this) == rhs); }
};
typedef std::vector<AddressRange> AddressRangeVector;
// This represents an address range in an original image, and its corresponding
// range in the transformed image.
struct MappedRange {
// An address in the original image.
DWORD rva_original;
// The corresponding addresses in the transformed image.
DWORD rva_transformed;
// The length of the address range.
DWORD length;
// It is possible for code to be injected into a transformed image, for which
// there is no corresponding code in the original image. If this range of
// transformed image is immediately followed by such injected code we maintain
// a record of its length here.
DWORD injected;
// It is possible for code to be removed from the original image. This happens
// for things like padding between blocks. There is no actual content lost,
// but the spacing between items may be lost. This keeps track of any removed
// content immediately following the |original| range.
DWORD removed;
};
// A vector of mapped ranges is used as a more useful representation of
// OMAP data.
typedef std::vector<MappedRange> Mapping;
// Used as a secondary search structure accompanying a Mapping.
struct EndpointIndex {
DWORD endpoint;
size_t index;
};
typedef std::vector<EndpointIndex> EndpointIndexMap;
// An ImageMap is vector of mapped ranges, plus a secondary index into it for
// doing interval searches. (An interval tree would also work, but is overkill
// because we don't need insertion and deletion.)
struct ImageMap {
// This is a description of the mapping between original and transformed
// image, sorted by addresses in the original image.
Mapping mapping;
// For all interval endpoints in |mapping| this stores the minimum index of
// an interval in |mapping| that contains the endpoint. Useful for doing
// interval intersection queries.
EndpointIndexMap endpoint_index_map;
};
} // namespace google_breakpad
#endif // COMMON_WINDOWS_OMAP_INTERNAL_H_

View File

@@ -74,7 +74,7 @@ enum UnwindOperationCodes {
UWOP_SET_FPREG, /* no info, FP = RSP + UNWIND_INFO.FPRegOffset*16 */
UWOP_SAVE_NONVOL, /* info == register number, offset in next slot */
UWOP_SAVE_NONVOL_FAR, /* info == register number, offset in next 2 slots */
//XXX: these are missing from MSDN!
// XXX: these are missing from MSDN!
// See: http://www.osronline.com/ddkx/kmarch/64bitamd_4rs7.htm
UWOP_SAVE_XMM,
UWOP_SAVE_XMM_FAR,
@@ -125,8 +125,19 @@ PDBSourceLineWriter::PDBSourceLineWriter() : output_(NULL) {
PDBSourceLineWriter::~PDBSourceLineWriter() {
}
bool PDBSourceLineWriter::SetCodeFile(const wstring &exe_file) {
if (code_file_.empty()) {
code_file_ = exe_file;
return true;
}
// Setting a different code file path is an error. It is success only if the
// file paths are the same.
return exe_file == code_file_;
}
bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) {
Close();
code_file_.clear();
if (FAILED(CoInitialize(NULL))) {
fprintf(stderr, "CoInitialize failed\n");
@@ -140,6 +151,7 @@ bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) {
StringFromGUID2(CLSID_DiaSource, classid, kGuidSize);
// vc80 uses bce36434-2c24-499e-bf49-8bd99b0eeb68.
// vc90 uses 4C41678E-887B-4365-A09E-925D28DB33C2.
// vc100 uses B86AE24D-BF2F-4AC9-B5A2-34B14E4CE11D.
fprintf(stderr, "CoCreateInstance CLSID_DiaSource %S failed "
"(msdia*.dll unregistered?)\n", classid);
return false;
@@ -162,7 +174,8 @@ bool PDBSourceLineWriter::Open(const wstring &file, FileFormat format) {
case ANY_FILE:
if (FAILED(data_source->loadDataFromPdb(file.c_str()))) {
if (FAILED(data_source->loadDataForExe(file.c_str(), NULL, NULL))) {
fprintf(stderr, "loadDataForPdb and loadDataFromExe failed for %ws\n", file.c_str());
fprintf(stderr, "loadDataForPdb and loadDataFromExe failed for %ws\n",
file.c_str());
return false;
}
code_file_ = file;
@@ -641,7 +654,7 @@ bool PDBSourceLineWriter::PrintFrameDataUsingEXE() {
unwind_rva,
&img->LastRvaSection));
DWORD stack_size = 8; // minimal stack size is 8 for RIP
DWORD stack_size = 8; // minimal stack size is 8 for RIP
DWORD rip_offset = 8;
do {
for (UBYTE c = 0; c < unwind_info->count_of_codes; c++) {
@@ -674,12 +687,12 @@ bool PDBSourceLineWriter::PrintFrameDataUsingEXE() {
break;
case UWOP_SAVE_NONVOL:
case UWOP_SAVE_XMM128: {
c++; //skip slot with offset
c++; // skip slot with offset
break;
}
case UWOP_SAVE_NONVOL_FAR:
case UWOP_SAVE_XMM128_FAR: {
c += 2; //skip 2 slots with offset
c += 2; // skip 2 slots with offset
break;
}
case UWOP_PUSH_MACHFRAME: {
@@ -832,7 +845,7 @@ bool PDBSourceLineWriter::FindPEFile() {
CComBSTR symbols_file;
if (SUCCEEDED(global->get_symbolsFileName(&symbols_file))) {
wstring file(symbols_file);
// Look for an EXE or DLL file.
const wchar_t *extensions[] = { L"exe", L"dll" };
for (int i = 0; i < sizeof(extensions) / sizeof(extensions[0]); i++) {
@@ -1064,7 +1077,7 @@ bool PDBSourceLineWriter::WriteMap(FILE *map_file) {
// This is not a critical piece of the symbol file.
PrintPEInfo();
ret = ret &&
PrintSourceFiles() &&
PrintSourceFiles() &&
PrintFunctions() &&
PrintFrameData();
@@ -1206,8 +1219,7 @@ bool PDBSourceLineWriter::GetPEInfo(PEModuleInfo *info) {
if (opt->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
// 64-bit PE file.
SizeOfImage = opt->SizeOfImage;
}
else {
} else {
// 32-bit PE file.
SizeOfImage = img->FileHeader->OptionalHeader.SizeOfImage;
}

View File

@@ -30,8 +30,8 @@
// PDBSourceLineWriter uses a pdb file produced by Visual C++ to output
// a line/address map for use with BasicSourceLineResolver.
#ifndef _PDB_SOURCE_LINE_WRITER_H__
#define _PDB_SOURCE_LINE_WRITER_H__
#ifndef COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
#define COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_
#include <atlcomcli.h>
@@ -101,10 +101,14 @@ class PDBSourceLineWriter {
// Returns true on success.
bool Open(const wstring &file, FileFormat format);
// Locates the pdb file for the given executable (exe or dll) file,
// and opens it. If there is already a pdb file open, it is automatically
// closed. Returns true on success.
bool OpenExecutable(const wstring &exe_file);
// Sets the code file full path. This is optional for 32-bit modules. It is
// also optional for 64-bit modules when there is an executable file stored
// in the same directory as the PDB file. It is only required for 64-bit
// modules when the executable file is not in the same location as the PDB
// file and it must be called after Open() and before WriteMap().
// If Open() was called for an executable file, then it is an error to call
// SetCodeFile() with a different file path and it will return false.
bool SetCodeFile(const wstring &exe_file);
// Writes a map file from the current pdb file to the given file stream.
// Returns true on success.
@@ -179,12 +183,12 @@ class PDBSourceLineWriter {
// and an ID is stored for it, or false if it has not.
bool FileIDIsCached(const wstring &file) {
return unique_files_.find(file) != unique_files_.end();
};
}
// Cache this filename and ID for later reuse.
void CacheFileID(const wstring &file, DWORD id) {
unique_files_[file] = id;
};
}
// Store this ID in the cache as a duplicate for this filename.
void StoreDuplicateFileID(const wstring &file, DWORD id) {
@@ -193,7 +197,7 @@ class PDBSourceLineWriter {
// map this id to the previously seen one
file_ids_[id] = iter->second;
}
};
}
// Given a file's unique ID, return the ID that should be used to
// reference it. There may be multiple files with identical filenames
@@ -204,7 +208,7 @@ class PDBSourceLineWriter {
if (iter == file_ids_.end())
return id;
return iter->second;
};
}
// Find the PE file corresponding to the loaded PDB file, and
// set the code_file_ member. Returns false on failure.
@@ -250,4 +254,4 @@ class PDBSourceLineWriter {
} // namespace google_breakpad
#endif // _PDB_SOURCE_LINE_WRITER_H__
#endif // COMMON_WINDOWS_PDB_SOURCE_LINE_WRITER_H_

View File

@@ -30,8 +30,8 @@
// string_utils-inl.h: Safer string manipulation on Windows, supporting
// pre-MSVC8 environments.
#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H__
#define COMMON_WINDOWS_STRING_UTILS_INL_H__
#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H_
#define COMMON_WINDOWS_STRING_UTILS_INL_H_
#include <stdarg.h>
#include <wchar.h>
@@ -139,4 +139,4 @@ inline void WindowsStringUtils::safe_wcsncpy(wchar_t *destination,
} // namespace google_breakpad
#endif // COMMON_WINDOWS_STRING_UTILS_INL_H__
#endif // COMMON_WINDOWS_STRING_UTILS_INL_H_