From e469f8cf4bd12d0addb2f2a37962819a8644622b Mon Sep 17 00:00:00 2001 From: "ivanpe@chromium.org" Date: Mon, 17 Nov 2014 22:47:05 +0000 Subject: [PATCH] Add parameter --product to symupload.exe Adding an optional parameter --product to symupload.exe. If specified it will be passed to the symbol server as POST parameter 'product'. As part of this, I'm also fixing: - Removed the .vcproj file as it can be generated from the .gyp file on demand. - error C4335: Mac file format detected. Fixed the line endings for omap.cc and dia_util.cc. - warning C4003: not enough actual parameters for macro 'max' Symupload.exe was compiled using MSVS 2013 and DIA SDK 12.0. Review URL: https://breakpad.appspot.com/9734002/ git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1402 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/common/windows/dia_util.cc | 2 +- src/common/windows/omap.cc | 1388 +++++++++--------- src/common/windows/pdb_source_line_writer.cc | 2 + src/tools/windows/binaries/symupload.exe | Bin 206336 -> 195072 bytes src/tools/windows/symupload/symupload.cc | 53 +- src/tools/windows/symupload/symupload.vcproj | 251 ---- 6 files changed, 737 insertions(+), 959 deletions(-) delete mode 100644 src/tools/windows/symupload/symupload.vcproj diff --git a/src/common/windows/dia_util.cc b/src/common/windows/dia_util.cc index 25a9a33f..ed8cb5b6 100644 --- a/src/common/windows/dia_util.cc +++ b/src/common/windows/dia_util.cc @@ -89,4 +89,4 @@ bool FindTable(REFIID iid, IDiaSession* session, void** table) { return false; } -} // namespace google_breakpad +} // namespace google_breakpad \ No newline at end of file diff --git a/src/common/windows/omap.cc b/src/common/windows/omap.cc index 129ee4ae..67b92065 100644 --- a/src/common/windows/omap.cc +++ b/src/common/windows/omap.cc @@ -1,694 +1,694 @@ -// 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. - -// This contains a suite of tools for transforming symbol information when -// when that information has been extracted from a PDB containing OMAP -// information. - -// OMAP information is a lightweight description of a mapping between two -// address spaces. It consists of two streams, each of them a vector 2-tuples. -// The OMAPTO stream contains tuples of the form -// -// (RVA in transformed image, RVA in original image) -// -// while the OMAPFROM stream contains tuples of the form -// -// (RVA in original image, RVA in transformed image) -// -// The entries in each vector are sorted by the first value of the tuple, and -// the lengths associated with a mapping are implicit as the distance between -// two successive addresses in the vector. - -// Consider a trivial 10-byte function described by the following symbol: -// -// Function: RVA 0x00001000, length 10, "foo" -// -// Now consider the same function, but with 5-bytes of instrumentation injected -// at offset 5. The OMAP streams describing this would look like: -// -// OMAPTO : [ [0x00001000, 0x00001000], -// [0x00001005, 0xFFFFFFFF], -// [0x0000100a, 0x00001005] ] -// OMAPFROM: [ [0x00001000, 0x00001000], -// [0x00001005, 0x0000100a] ] -// -// In this case the injected code has been marked as not originating in the -// source image, and thus it will have no symbol information at all. However, -// the injected code may also be associated with an original address range; -// for example, when prepending instrumentation to a basic block the -// instrumentation can be labelled as originating from the same source BB such -// that symbol resolution will still find the appropriate source code line -// number. In this case the OMAP stream would look like: -// -// OMAPTO : [ [0x00001000, 0x00001000], -// [0x00001005, 0x00001005], -// [0x0000100a, 0x00001005] ] -// OMAPFROM: [ [0x00001000, 0x00001000], -// [0x00001005, 0x0000100a] ] -// -// Suppose we asked DIA to lookup the symbol at location 0x0000100a of the -// instrumented image. It would first run this through the OMAPTO table and -// translate that address to 0x00001005. It would then lookup the symbol -// at that address and return the symbol for the function "foo". This is the -// correct result. -// -// However, if we query DIA for the length and address of the symbol it will -// tell us that it has length 10 and is at RVA 0x00001000. The location is -// correct, but the length doesn't take into account the 5-bytes of injected -// code. Symbol resolution works (starting from an instrumented address, -// mapping to an original address, and looking up a symbol), but the symbol -// metadata is incorrect. -// -// If we dump the symbols using DIA they will have their addresses -// appropriately transformed and reflect positions in the instrumented image. -// However, if we try to do a lookup using those symbols resolution can fail. -// For example, the address 0x0000100a will not map to the symbol for "foo", -// because DIA tells us it is at location 0x00001000 (correct) with length -// 10 (incorrect). The problem is one of order of operations: in this case -// we're attempting symbol resolution by looking up an instrumented address -// in the table of translated symbols. -// -// One way to handle this is to dump the OMAP information as part of the -// breakpad symbols. This requires the rest of the toolchain to be aware of -// OMAP information and to use it when present prior to performing lookup. The -// other option is to properly transform the symbols (updating length as well as -// position) so that resolution will work as expected for translated addresses. -// This is transparent to the rest of the toolchain. - -#include "common/windows/omap.h" - -#include - -#include -#include -#include - -#include "common/windows/dia_util.h" - -namespace google_breakpad { - -namespace { - -static const wchar_t kOmapToDebugStreamName[] = L"OMAPTO"; -static const wchar_t kOmapFromDebugStreamName[] = L"OMAPFROM"; - -// Dependending on where this is used in breakpad we sometimes get min/max from -// windef, and other times from algorithm. To get around this we simply -// define our own min/max functions. -template -const T& Min(const T& t1, const T& t2) { return t1 < t2 ? t1 : t2; } -template -const T& Max(const T& t1, const T& t2) { return t1 > t2 ? t1 : t2; } - -// It makes things more readable to have two different OMAP types. We cast -// normal OMAPs into these. They must be the same size as the OMAP structure -// for this to work, hence the static asserts. -struct OmapOrigToTran { - DWORD rva_original; - DWORD rva_transformed; -}; -struct OmapTranToOrig { - DWORD rva_transformed; - DWORD rva_original; -}; -static_assert(sizeof(OmapOrigToTran) == sizeof(OMAP), - "OmapOrigToTran must have same size as OMAP."); -static_assert(sizeof(OmapTranToOrig) == sizeof(OMAP), - "OmapTranToOrig must have same size as OMAP."); -typedef std::vector OmapFromTable; -typedef std::vector OmapToTable; - -// Used for sorting and searching through a Mapping. -bool MappedRangeOriginalLess(const MappedRange& lhs, const MappedRange& rhs) { - if (lhs.rva_original < rhs.rva_original) - return true; - if (lhs.rva_original > rhs.rva_original) - return false; - return lhs.length < rhs.length; -} -bool MappedRangeMappedLess(const MappedRange& lhs, const MappedRange& rhs) { - if (lhs.rva_transformed < rhs.rva_transformed) - return true; - if (lhs.rva_transformed > rhs.rva_transformed) - return false; - return lhs.length < rhs.length; -} - -// Used for searching through the EndpointIndexMap. -bool EndpointIndexLess(const EndpointIndex& ei1, const EndpointIndex& ei2) { - return ei1.endpoint < ei2.endpoint; -} - -// Finds the debug stream with the given |name| in the given |session|, and -// populates |table| with its contents. Casts the data directly into OMAP -// structs. -bool FindAndLoadOmapTable(const wchar_t* name, - IDiaSession* session, - OmapTable* table) { - assert(name != NULL); - assert(session != NULL); - assert(table != NULL); - - CComPtr stream; - if (!FindDebugStream(name, session, &stream)) - return false; - assert(stream.p != NULL); - - LONG count = 0; - if (FAILED(stream->get_Count(&count))) { - fprintf(stderr, "IDiaEnumDebugStreamData::get_Count failed for stream " - "\"%ws\"\n", name); - return false; - } - - // Get the length of the stream in bytes. - DWORD bytes_read = 0; - ULONG count_read = 0; - if (FAILED(stream->Next(count, 0, &bytes_read, NULL, &count_read))) { - fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " - "length of stream \"%ws\"\n", name); - return false; - } - - // Ensure it's consistent with the OMAP data type. - DWORD bytes_expected = count * sizeof(OmapTable::value_type); - if (count * sizeof(OmapTable::value_type) != bytes_read) { - fprintf(stderr, "DIA debug stream \"%ws\" has an unexpected length", name); - return false; - } - - // Read the table. - table->resize(count); - bytes_read = 0; - count_read = 0; - if (FAILED(stream->Next(count, bytes_expected, &bytes_read, - reinterpret_cast(&table->at(0)), - &count_read))) { - fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " - "data from stream \"%ws\"\n"); - return false; - } - - return true; -} - -// This determines the original image length by looking through the segment -// table. -bool GetOriginalImageLength(IDiaSession* session, DWORD* image_length) { - assert(session != NULL); - assert(image_length != NULL); - - CComPtr enum_segments; - if (!FindTable(session, &enum_segments)) - return false; - assert(enum_segments.p != NULL); - - DWORD temp_image_length = 0; - CComPtr segment; - ULONG fetched = 0; - while (SUCCEEDED(enum_segments->Next(1, &segment, &fetched)) && - fetched == 1) { - assert(segment.p != NULL); - - DWORD rva = 0; - DWORD length = 0; - DWORD frame = 0; - if (FAILED(segment->get_relativeVirtualAddress(&rva)) || - FAILED(segment->get_length(&length)) || - FAILED(segment->get_frame(&frame))) { - fprintf(stderr, "Failed to get basic properties for IDiaSegment\n"); - return false; - } - - if (frame > 0) { - DWORD segment_end = rva + length; - if (segment_end > temp_image_length) - temp_image_length = segment_end; - } - segment.Release(); - } - - *image_length = temp_image_length; - return true; -} - -// Detects regions of the original image that have been removed in the -// transformed image, and sets the 'removed' property on all mapped ranges -// immediately preceding a gap. The mapped ranges must be sorted by -// 'rva_original'. -void FillInRemovedLengths(Mapping* mapping) { - assert(mapping != NULL); - - // Find and fill gaps. We do this with two sweeps. We first sweep forward - // looking for gaps. When we identify a gap we then sweep forward with a - // second scan and set the 'removed' property for any intervals that - // immediately precede the gap. - // - // Gaps are typically between two successive intervals, but not always: - // - // Range 1: --------------- - // Range 2: ------- - // Range 3: ------------- - // Gap : ****** - // - // In the above example the gap is between range 1 and range 3. A forward - // sweep finds the gap, and a second forward sweep identifies that range 1 - // immediately precedes the gap and sets its 'removed' property. - - size_t fill = 0; - DWORD rva_front = 0; - for (size_t find = 0; find < mapping->size(); ++find) { -#ifndef NDEBUG - // We expect the mapped ranges to be sorted by 'rva_original'. - if (find > 0) { - assert(mapping->at(find - 1).rva_original <= - mapping->at(find).rva_original); - } -#endif - - if (rva_front < mapping->at(find).rva_original) { - // We've found a gap. Fill it in by setting the 'removed' property for - // any affected intervals. - DWORD removed = mapping->at(find).rva_original - rva_front; - for (; fill < find; ++fill) { - if (mapping->at(fill).rva_original + mapping->at(fill).length != - rva_front) { - continue; - } - - // This interval ends right where the gap starts. It needs to have its - // 'removed' information filled in. - mapping->at(fill).removed = removed; - } - } - - // Advance the front that indicates the covered portion of the image. - rva_front = mapping->at(find).rva_original + mapping->at(find).length; - } -} - -// Builds a unified view of the mapping between the original and transformed -// image space by merging OMAPTO and OMAPFROM data. -void BuildMapping(const OmapData& omap_data, Mapping* mapping) { - assert(mapping != NULL); - - mapping->clear(); - - if (omap_data.omap_from.empty() || omap_data.omap_to.empty()) - return; - - // The names 'omap_to' and 'omap_from' are awfully confusing, so we make - // ourselves more explicit here. This cast is only safe because the underlying - // types have the exact same size. - const OmapToTable& tran2orig = - reinterpret_cast(omap_data.omap_to); - const OmapFromTable& orig2tran = reinterpret_cast( - omap_data.omap_from); - - // Handle the range of data at the beginning of the image. This is not usually - // specified by the OMAP data. - if (tran2orig[0].rva_transformed > 0 && orig2tran[0].rva_original > 0) { - DWORD header_transformed = tran2orig[0].rva_transformed; - DWORD header_original = orig2tran[0].rva_original; - DWORD header = Min(header_transformed, header_original); - - MappedRange mr = {}; - mr.length = header; - mr.injected = header_transformed - header; - mr.removed = header_original - header; - mapping->push_back(mr); - } - - // Convert the implied lengths to explicit lengths, and infer which content - // has been injected into the transformed image. Injected content is inferred - // as regions of the transformed address space that does not map back to - // known valid content in the original image. - for (size_t i = 0; i < tran2orig.size(); ++i) { - const OmapTranToOrig& o1 = tran2orig[i]; - - // This maps to content that is outside the original image, thus it - // describes injected content. We can skip this entry. - if (o1.rva_original >= omap_data.length_original) - continue; - - // Calculate the length of the current OMAP entry. This is implicit as the - // distance between successive |rva| values, capped at the end of the - // original image. - DWORD length = 0; - if (i + 1 < tran2orig.size()) { - const OmapTranToOrig& o2 = tran2orig[i + 1]; - - // We expect the table to be sorted by rva_transformed. - assert(o1.rva_transformed <= o2.rva_transformed); - - length = o2.rva_transformed - o1.rva_transformed; - if (o1.rva_original + length > omap_data.length_original) { - length = omap_data.length_original - o1.rva_original; - } - } else { - length = omap_data.length_original - o1.rva_original; - } - - // Zero-length entries don't describe anything and can be ignored. - if (length == 0) - continue; - - // Any gaps in the transformed address-space are due to injected content. - if (!mapping->empty()) { - MappedRange& prev_mr = mapping->back(); - prev_mr.injected += o1.rva_transformed - - (prev_mr.rva_transformed + prev_mr.length); - } - - MappedRange mr = {}; - mr.rva_original = o1.rva_original; - mr.rva_transformed = o1.rva_transformed; - mr.length = length; - mapping->push_back(mr); - } - - // Sort based on the original image addresses. - std::sort(mapping->begin(), mapping->end(), MappedRangeOriginalLess); - - // Fill in the 'removed' lengths by looking for gaps in the coverage of the - // original address space. - FillInRemovedLengths(mapping); - - return; -} - -void BuildEndpointIndexMap(ImageMap* image_map) { - assert(image_map != NULL); - - if (image_map->mapping.size() == 0) - return; - - const Mapping& mapping = image_map->mapping; - EndpointIndexMap& eim = image_map->endpoint_index_map; - - // Get the unique set of interval endpoints. - std::set endpoints; - for (size_t i = 0; i < mapping.size(); ++i) { - endpoints.insert(mapping[i].rva_original); - endpoints.insert(mapping[i].rva_original + - mapping[i].length + - mapping[i].removed); - } - - // Use the endpoints to initialize the secondary search structure for the - // mapping. - eim.resize(endpoints.size()); - std::set::const_iterator it = endpoints.begin(); - for (size_t i = 0; it != endpoints.end(); ++it, ++i) { - eim[i].endpoint = *it; - eim[i].index = mapping.size(); - } - - // For each endpoint we want the smallest index of any interval containing - // it. We iterate over the intervals and update the indices associated with - // each interval endpoint contained in the current interval. In the general - // case of an arbitrary set of intervals this is O(n^2), but the structure of - // OMAP data makes this O(n). - for (size_t i = 0; i < mapping.size(); ++i) { - EndpointIndex ei1 = { mapping[i].rva_original, 0 }; - EndpointIndexMap::iterator it1 = std::lower_bound( - eim.begin(), eim.end(), ei1, EndpointIndexLess); - - EndpointIndex ei2 = { mapping[i].rva_original + mapping[i].length + - mapping[i].removed, 0 }; - EndpointIndexMap::iterator it2 = std::lower_bound( - eim.begin(), eim.end(), ei2, EndpointIndexLess); - - for (; it1 != it2; ++it1) - it1->index = Min(i, it1->index); - } -} - -// Clips the given mapped range. -void ClipMappedRangeOriginal(const AddressRange& clip_range, - MappedRange* mapped_range) { - assert(mapped_range != NULL); - - // The clipping range is entirely outside of the mapped range. - if (clip_range.end() <= mapped_range->rva_original || - mapped_range->rva_original + mapped_range->length + - mapped_range->removed <= clip_range.rva) { - mapped_range->length = 0; - mapped_range->injected = 0; - mapped_range->removed = 0; - return; - } - - // Clip the left side. - if (mapped_range->rva_original < clip_range.rva) { - DWORD clip_left = clip_range.rva - mapped_range->rva_original; - mapped_range->rva_original += clip_left; - mapped_range->rva_transformed += clip_left; - - if (clip_left > mapped_range->length) { - // The left clipping boundary entirely erases the content section of the - // range. - DWORD trim = clip_left - mapped_range->length; - mapped_range->length = 0; - mapped_range->injected -= Min(trim, mapped_range->injected); - // We know that trim <= mapped_range->remove. - mapped_range->removed -= trim; - } else { - // The left clipping boundary removes some, but not all, of the content. - // As such it leaves the removed/injected component intact. - mapped_range->length -= clip_left; - } - } - - // Clip the right side. - DWORD end_original = mapped_range->rva_original + mapped_range->length; - if (clip_range.end() < end_original) { - // The right clipping boundary lands in the 'content' section of the range, - // entirely clearing the injected/removed portion. - DWORD clip_right = end_original - clip_range.end(); - mapped_range->length -= clip_right; - mapped_range->injected = 0; - mapped_range->removed = 0; - return; - } else { - // The right clipping boundary is outside of the content, but may affect - // the removed/injected portion of the range. - DWORD end_removed = end_original + mapped_range->removed; - if (clip_range.end() < end_removed) - mapped_range->removed = clip_range.end() - end_original; - - DWORD end_injected = end_original + mapped_range->injected; - if (clip_range.end() < end_injected) - mapped_range->injected = clip_range.end() - end_original; - } - - return; -} - -} // namespace - -int AddressRange::Compare(const AddressRange& rhs) const { - if (end() <= rhs.rva) - return -1; - if (rhs.end() <= rva) - return 1; - return 0; -} - -bool GetOmapDataAndDisableTranslation(IDiaSession* session, - OmapData* omap_data) { - assert(session != NULL); - assert(omap_data != NULL); - - CComPtr address_map; - if (FAILED(session->QueryInterface(&address_map))) { - fprintf(stderr, "IDiaSession::QueryInterface(IDiaAddressMap) failed\n"); - return false; - } - assert(address_map.p != NULL); - - BOOL omap_enabled = FALSE; - if (FAILED(address_map->get_addressMapEnabled(&omap_enabled))) { - fprintf(stderr, "IDiaAddressMap::get_addressMapEnabled failed\n"); - return false; - } - - if (!omap_enabled) { - // We indicate the non-presence of OMAP data by returning empty tables. - omap_data->omap_from.clear(); - omap_data->omap_to.clear(); - omap_data->length_original = 0; - return true; - } - - // OMAP data is present. Disable translation. - if (FAILED(address_map->put_addressMapEnabled(FALSE))) { - fprintf(stderr, "IDiaAddressMap::put_addressMapEnabled failed\n"); - return false; - } - - // Read the OMAP streams. - if (!FindAndLoadOmapTable(kOmapFromDebugStreamName, - session, - &omap_data->omap_from)) { - return false; - } - if (!FindAndLoadOmapTable(kOmapToDebugStreamName, - session, - &omap_data->omap_to)) { - return false; - } - - // Get the lengths of the address spaces. - if (!GetOriginalImageLength(session, &omap_data->length_original)) - return false; - - return true; -} - -void BuildImageMap(const OmapData& omap_data, ImageMap* image_map) { - assert(image_map != NULL); - - BuildMapping(omap_data, &image_map->mapping); - BuildEndpointIndexMap(image_map); -} - -void MapAddressRange(const ImageMap& image_map, - const AddressRange& original_range, - AddressRangeVector* mapped_ranges) { - assert(mapped_ranges != NULL); - - const Mapping& map = image_map.mapping; - - // Handle the trivial case of an empty image_map. This means that there is - // no transformation to be applied, and we can simply return the original - // range. - if (map.empty()) { - mapped_ranges->push_back(original_range); - return; - } - - // If we get a query of length 0 we need to handle it by using a non-zero - // query length. - AddressRange query_range(original_range); - if (query_range.length == 0) - query_range.length = 1; - - // Find the range of intervals that can potentially intersect our query range. - size_t imin = 0; - size_t imax = 0; - { - // The index of the earliest possible range that can affect is us done by - // searching through the secondary indexing structure. - const EndpointIndexMap& eim = image_map.endpoint_index_map; - EndpointIndex q1 = { query_range.rva, 0 }; - EndpointIndexMap::const_iterator it1 = std::lower_bound( - eim.begin(), eim.end(), q1, EndpointIndexLess); - if (it1 == eim.end()) { - imin = map.size(); - } else { - // Backup to find the interval that contains our query point. - if (it1 != eim.begin() && query_range.rva < it1->endpoint) - --it1; - imin = it1->index; - } - - // The first range that can't possibly intersect us is found by searching - // through the image map directly as it is already sorted by interval start - // point. - MappedRange q2 = { query_range.end(), 0 }; - Mapping::const_iterator it2 = std::lower_bound( - map.begin(), map.end(), q2, MappedRangeOriginalLess); - imax = it2 - map.begin(); - } - - // Find all intervals that intersect the query range. - Mapping temp_map; - for (size_t i = imin; i < imax; ++i) { - MappedRange mr = map[i]; - ClipMappedRangeOriginal(query_range, &mr); - if (mr.length + mr.injected > 0) - temp_map.push_back(mr); - } - - // If there are no intersecting ranges then the query range has been removed - // from the image in question. - if (temp_map.empty()) - return; - - // Sort based on transformed addresses. - std::sort(temp_map.begin(), temp_map.end(), MappedRangeMappedLess); - - // Zero-length queries can't actually be merged. We simply output the set of - // unique RVAs that correspond to the query RVA. - if (original_range.length == 0) { - mapped_ranges->push_back(AddressRange(temp_map[0].rva_transformed, 0)); - for (size_t i = 1; i < temp_map.size(); ++i) { - if (temp_map[i].rva_transformed > mapped_ranges->back().rva) - mapped_ranges->push_back(AddressRange(temp_map[i].rva_transformed, 0)); - } - return; - } - - // Merge any ranges that are consecutive in the mapped image. We merge over - // injected content if it makes ranges contiguous, but we ignore any injected - // content at the tail end of a range. This allows us to detect symbols that - // have been lengthened by injecting content in the middle. However, it - // misses the case where content has been injected at the head or the tail. - // The problem is that it doesn't know whether to attribute it to the - // preceding or following symbol. It is up to the author of the transform to - // output explicit OMAP info in these cases to ensure full coverage of the - // transformed address space. - DWORD rva_begin = temp_map[0].rva_transformed; - DWORD rva_cur_content = rva_begin + temp_map[0].length; - DWORD rva_cur_injected = rva_cur_content + temp_map[0].injected; - for (size_t i = 1; i < temp_map.size(); ++i) { - if (rva_cur_injected < temp_map[i].rva_transformed) { - // This marks the end of a continuous range in the image. Output the - // current range and start a new one. - if (rva_begin < rva_cur_content) { - mapped_ranges->push_back( - AddressRange(rva_begin, rva_cur_content - rva_begin)); - } - rva_begin = temp_map[i].rva_transformed; - } - - rva_cur_content = temp_map[i].rva_transformed + temp_map[i].length; - rva_cur_injected = rva_cur_content + temp_map[i].injected; - } - - // Output the range in progress. - if (rva_begin < rva_cur_content) { - mapped_ranges->push_back( - AddressRange(rva_begin, rva_cur_content - rva_begin)); - } - - return; -} - -} // 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. + +// This contains a suite of tools for transforming symbol information when +// when that information has been extracted from a PDB containing OMAP +// information. + +// OMAP information is a lightweight description of a mapping between two +// address spaces. It consists of two streams, each of them a vector 2-tuples. +// The OMAPTO stream contains tuples of the form +// +// (RVA in transformed image, RVA in original image) +// +// while the OMAPFROM stream contains tuples of the form +// +// (RVA in original image, RVA in transformed image) +// +// The entries in each vector are sorted by the first value of the tuple, and +// the lengths associated with a mapping are implicit as the distance between +// two successive addresses in the vector. + +// Consider a trivial 10-byte function described by the following symbol: +// +// Function: RVA 0x00001000, length 10, "foo" +// +// Now consider the same function, but with 5-bytes of instrumentation injected +// at offset 5. The OMAP streams describing this would look like: +// +// OMAPTO : [ [0x00001000, 0x00001000], +// [0x00001005, 0xFFFFFFFF], +// [0x0000100a, 0x00001005] ] +// OMAPFROM: [ [0x00001000, 0x00001000], +// [0x00001005, 0x0000100a] ] +// +// In this case the injected code has been marked as not originating in the +// source image, and thus it will have no symbol information at all. However, +// the injected code may also be associated with an original address range; +// for example, when prepending instrumentation to a basic block the +// instrumentation can be labelled as originating from the same source BB such +// that symbol resolution will still find the appropriate source code line +// number. In this case the OMAP stream would look like: +// +// OMAPTO : [ [0x00001000, 0x00001000], +// [0x00001005, 0x00001005], +// [0x0000100a, 0x00001005] ] +// OMAPFROM: [ [0x00001000, 0x00001000], +// [0x00001005, 0x0000100a] ] +// +// Suppose we asked DIA to lookup the symbol at location 0x0000100a of the +// instrumented image. It would first run this through the OMAPTO table and +// translate that address to 0x00001005. It would then lookup the symbol +// at that address and return the symbol for the function "foo". This is the +// correct result. +// +// However, if we query DIA for the length and address of the symbol it will +// tell us that it has length 10 and is at RVA 0x00001000. The location is +// correct, but the length doesn't take into account the 5-bytes of injected +// code. Symbol resolution works (starting from an instrumented address, +// mapping to an original address, and looking up a symbol), but the symbol +// metadata is incorrect. +// +// If we dump the symbols using DIA they will have their addresses +// appropriately transformed and reflect positions in the instrumented image. +// However, if we try to do a lookup using those symbols resolution can fail. +// For example, the address 0x0000100a will not map to the symbol for "foo", +// because DIA tells us it is at location 0x00001000 (correct) with length +// 10 (incorrect). The problem is one of order of operations: in this case +// we're attempting symbol resolution by looking up an instrumented address +// in the table of translated symbols. +// +// One way to handle this is to dump the OMAP information as part of the +// breakpad symbols. This requires the rest of the toolchain to be aware of +// OMAP information and to use it when present prior to performing lookup. The +// other option is to properly transform the symbols (updating length as well as +// position) so that resolution will work as expected for translated addresses. +// This is transparent to the rest of the toolchain. + +#include "common/windows/omap.h" + +#include + +#include +#include +#include + +#include "common/windows/dia_util.h" + +namespace google_breakpad { + +namespace { + +static const wchar_t kOmapToDebugStreamName[] = L"OMAPTO"; +static const wchar_t kOmapFromDebugStreamName[] = L"OMAPFROM"; + +// Dependending on where this is used in breakpad we sometimes get min/max from +// windef, and other times from algorithm. To get around this we simply +// define our own min/max functions. +template +const T& Min(const T& t1, const T& t2) { return t1 < t2 ? t1 : t2; } +template +const T& Max(const T& t1, const T& t2) { return t1 > t2 ? t1 : t2; } + +// It makes things more readable to have two different OMAP types. We cast +// normal OMAPs into these. They must be the same size as the OMAP structure +// for this to work, hence the static asserts. +struct OmapOrigToTran { + DWORD rva_original; + DWORD rva_transformed; +}; +struct OmapTranToOrig { + DWORD rva_transformed; + DWORD rva_original; +}; +static_assert(sizeof(OmapOrigToTran) == sizeof(OMAP), + "OmapOrigToTran must have same size as OMAP."); +static_assert(sizeof(OmapTranToOrig) == sizeof(OMAP), + "OmapTranToOrig must have same size as OMAP."); +typedef std::vector OmapFromTable; +typedef std::vector OmapToTable; + +// Used for sorting and searching through a Mapping. +bool MappedRangeOriginalLess(const MappedRange& lhs, const MappedRange& rhs) { + if (lhs.rva_original < rhs.rva_original) + return true; + if (lhs.rva_original > rhs.rva_original) + return false; + return lhs.length < rhs.length; +} +bool MappedRangeMappedLess(const MappedRange& lhs, const MappedRange& rhs) { + if (lhs.rva_transformed < rhs.rva_transformed) + return true; + if (lhs.rva_transformed > rhs.rva_transformed) + return false; + return lhs.length < rhs.length; +} + +// Used for searching through the EndpointIndexMap. +bool EndpointIndexLess(const EndpointIndex& ei1, const EndpointIndex& ei2) { + return ei1.endpoint < ei2.endpoint; +} + +// Finds the debug stream with the given |name| in the given |session|, and +// populates |table| with its contents. Casts the data directly into OMAP +// structs. +bool FindAndLoadOmapTable(const wchar_t* name, + IDiaSession* session, + OmapTable* table) { + assert(name != NULL); + assert(session != NULL); + assert(table != NULL); + + CComPtr stream; + if (!FindDebugStream(name, session, &stream)) + return false; + assert(stream.p != NULL); + + LONG count = 0; + if (FAILED(stream->get_Count(&count))) { + fprintf(stderr, "IDiaEnumDebugStreamData::get_Count failed for stream " + "\"%ws\"\n", name); + return false; + } + + // Get the length of the stream in bytes. + DWORD bytes_read = 0; + ULONG count_read = 0; + if (FAILED(stream->Next(count, 0, &bytes_read, NULL, &count_read))) { + fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " + "length of stream \"%ws\"\n", name); + return false; + } + + // Ensure it's consistent with the OMAP data type. + DWORD bytes_expected = count * sizeof(OmapTable::value_type); + if (count * sizeof(OmapTable::value_type) != bytes_read) { + fprintf(stderr, "DIA debug stream \"%ws\" has an unexpected length", name); + return false; + } + + // Read the table. + table->resize(count); + bytes_read = 0; + count_read = 0; + if (FAILED(stream->Next(count, bytes_expected, &bytes_read, + reinterpret_cast(&table->at(0)), + &count_read))) { + fprintf(stderr, "IDiaEnumDebugStreamData::Next failed while reading " + "data from stream \"%ws\"\n"); + return false; + } + + return true; +} + +// This determines the original image length by looking through the segment +// table. +bool GetOriginalImageLength(IDiaSession* session, DWORD* image_length) { + assert(session != NULL); + assert(image_length != NULL); + + CComPtr enum_segments; + if (!FindTable(session, &enum_segments)) + return false; + assert(enum_segments.p != NULL); + + DWORD temp_image_length = 0; + CComPtr segment; + ULONG fetched = 0; + while (SUCCEEDED(enum_segments->Next(1, &segment, &fetched)) && + fetched == 1) { + assert(segment.p != NULL); + + DWORD rva = 0; + DWORD length = 0; + DWORD frame = 0; + if (FAILED(segment->get_relativeVirtualAddress(&rva)) || + FAILED(segment->get_length(&length)) || + FAILED(segment->get_frame(&frame))) { + fprintf(stderr, "Failed to get basic properties for IDiaSegment\n"); + return false; + } + + if (frame > 0) { + DWORD segment_end = rva + length; + if (segment_end > temp_image_length) + temp_image_length = segment_end; + } + segment.Release(); + } + + *image_length = temp_image_length; + return true; +} + +// Detects regions of the original image that have been removed in the +// transformed image, and sets the 'removed' property on all mapped ranges +// immediately preceding a gap. The mapped ranges must be sorted by +// 'rva_original'. +void FillInRemovedLengths(Mapping* mapping) { + assert(mapping != NULL); + + // Find and fill gaps. We do this with two sweeps. We first sweep forward + // looking for gaps. When we identify a gap we then sweep forward with a + // second scan and set the 'removed' property for any intervals that + // immediately precede the gap. + // + // Gaps are typically between two successive intervals, but not always: + // + // Range 1: --------------- + // Range 2: ------- + // Range 3: ------------- + // Gap : ****** + // + // In the above example the gap is between range 1 and range 3. A forward + // sweep finds the gap, and a second forward sweep identifies that range 1 + // immediately precedes the gap and sets its 'removed' property. + + size_t fill = 0; + DWORD rva_front = 0; + for (size_t find = 0; find < mapping->size(); ++find) { +#ifndef NDEBUG + // We expect the mapped ranges to be sorted by 'rva_original'. + if (find > 0) { + assert(mapping->at(find - 1).rva_original <= + mapping->at(find).rva_original); + } +#endif + + if (rva_front < mapping->at(find).rva_original) { + // We've found a gap. Fill it in by setting the 'removed' property for + // any affected intervals. + DWORD removed = mapping->at(find).rva_original - rva_front; + for (; fill < find; ++fill) { + if (mapping->at(fill).rva_original + mapping->at(fill).length != + rva_front) { + continue; + } + + // This interval ends right where the gap starts. It needs to have its + // 'removed' information filled in. + mapping->at(fill).removed = removed; + } + } + + // Advance the front that indicates the covered portion of the image. + rva_front = mapping->at(find).rva_original + mapping->at(find).length; + } +} + +// Builds a unified view of the mapping between the original and transformed +// image space by merging OMAPTO and OMAPFROM data. +void BuildMapping(const OmapData& omap_data, Mapping* mapping) { + assert(mapping != NULL); + + mapping->clear(); + + if (omap_data.omap_from.empty() || omap_data.omap_to.empty()) + return; + + // The names 'omap_to' and 'omap_from' are awfully confusing, so we make + // ourselves more explicit here. This cast is only safe because the underlying + // types have the exact same size. + const OmapToTable& tran2orig = + reinterpret_cast(omap_data.omap_to); + const OmapFromTable& orig2tran = reinterpret_cast( + omap_data.omap_from); + + // Handle the range of data at the beginning of the image. This is not usually + // specified by the OMAP data. + if (tran2orig[0].rva_transformed > 0 && orig2tran[0].rva_original > 0) { + DWORD header_transformed = tran2orig[0].rva_transformed; + DWORD header_original = orig2tran[0].rva_original; + DWORD header = Min(header_transformed, header_original); + + MappedRange mr = {}; + mr.length = header; + mr.injected = header_transformed - header; + mr.removed = header_original - header; + mapping->push_back(mr); + } + + // Convert the implied lengths to explicit lengths, and infer which content + // has been injected into the transformed image. Injected content is inferred + // as regions of the transformed address space that does not map back to + // known valid content in the original image. + for (size_t i = 0; i < tran2orig.size(); ++i) { + const OmapTranToOrig& o1 = tran2orig[i]; + + // This maps to content that is outside the original image, thus it + // describes injected content. We can skip this entry. + if (o1.rva_original >= omap_data.length_original) + continue; + + // Calculate the length of the current OMAP entry. This is implicit as the + // distance between successive |rva| values, capped at the end of the + // original image. + DWORD length = 0; + if (i + 1 < tran2orig.size()) { + const OmapTranToOrig& o2 = tran2orig[i + 1]; + + // We expect the table to be sorted by rva_transformed. + assert(o1.rva_transformed <= o2.rva_transformed); + + length = o2.rva_transformed - o1.rva_transformed; + if (o1.rva_original + length > omap_data.length_original) { + length = omap_data.length_original - o1.rva_original; + } + } else { + length = omap_data.length_original - o1.rva_original; + } + + // Zero-length entries don't describe anything and can be ignored. + if (length == 0) + continue; + + // Any gaps in the transformed address-space are due to injected content. + if (!mapping->empty()) { + MappedRange& prev_mr = mapping->back(); + prev_mr.injected += o1.rva_transformed - + (prev_mr.rva_transformed + prev_mr.length); + } + + MappedRange mr = {}; + mr.rva_original = o1.rva_original; + mr.rva_transformed = o1.rva_transformed; + mr.length = length; + mapping->push_back(mr); + } + + // Sort based on the original image addresses. + std::sort(mapping->begin(), mapping->end(), MappedRangeOriginalLess); + + // Fill in the 'removed' lengths by looking for gaps in the coverage of the + // original address space. + FillInRemovedLengths(mapping); + + return; +} + +void BuildEndpointIndexMap(ImageMap* image_map) { + assert(image_map != NULL); + + if (image_map->mapping.size() == 0) + return; + + const Mapping& mapping = image_map->mapping; + EndpointIndexMap& eim = image_map->endpoint_index_map; + + // Get the unique set of interval endpoints. + std::set endpoints; + for (size_t i = 0; i < mapping.size(); ++i) { + endpoints.insert(mapping[i].rva_original); + endpoints.insert(mapping[i].rva_original + + mapping[i].length + + mapping[i].removed); + } + + // Use the endpoints to initialize the secondary search structure for the + // mapping. + eim.resize(endpoints.size()); + std::set::const_iterator it = endpoints.begin(); + for (size_t i = 0; it != endpoints.end(); ++it, ++i) { + eim[i].endpoint = *it; + eim[i].index = mapping.size(); + } + + // For each endpoint we want the smallest index of any interval containing + // it. We iterate over the intervals and update the indices associated with + // each interval endpoint contained in the current interval. In the general + // case of an arbitrary set of intervals this is O(n^2), but the structure of + // OMAP data makes this O(n). + for (size_t i = 0; i < mapping.size(); ++i) { + EndpointIndex ei1 = { mapping[i].rva_original, 0 }; + EndpointIndexMap::iterator it1 = std::lower_bound( + eim.begin(), eim.end(), ei1, EndpointIndexLess); + + EndpointIndex ei2 = { mapping[i].rva_original + mapping[i].length + + mapping[i].removed, 0 }; + EndpointIndexMap::iterator it2 = std::lower_bound( + eim.begin(), eim.end(), ei2, EndpointIndexLess); + + for (; it1 != it2; ++it1) + it1->index = Min(i, it1->index); + } +} + +// Clips the given mapped range. +void ClipMappedRangeOriginal(const AddressRange& clip_range, + MappedRange* mapped_range) { + assert(mapped_range != NULL); + + // The clipping range is entirely outside of the mapped range. + if (clip_range.end() <= mapped_range->rva_original || + mapped_range->rva_original + mapped_range->length + + mapped_range->removed <= clip_range.rva) { + mapped_range->length = 0; + mapped_range->injected = 0; + mapped_range->removed = 0; + return; + } + + // Clip the left side. + if (mapped_range->rva_original < clip_range.rva) { + DWORD clip_left = clip_range.rva - mapped_range->rva_original; + mapped_range->rva_original += clip_left; + mapped_range->rva_transformed += clip_left; + + if (clip_left > mapped_range->length) { + // The left clipping boundary entirely erases the content section of the + // range. + DWORD trim = clip_left - mapped_range->length; + mapped_range->length = 0; + mapped_range->injected -= Min(trim, mapped_range->injected); + // We know that trim <= mapped_range->remove. + mapped_range->removed -= trim; + } else { + // The left clipping boundary removes some, but not all, of the content. + // As such it leaves the removed/injected component intact. + mapped_range->length -= clip_left; + } + } + + // Clip the right side. + DWORD end_original = mapped_range->rva_original + mapped_range->length; + if (clip_range.end() < end_original) { + // The right clipping boundary lands in the 'content' section of the range, + // entirely clearing the injected/removed portion. + DWORD clip_right = end_original - clip_range.end(); + mapped_range->length -= clip_right; + mapped_range->injected = 0; + mapped_range->removed = 0; + return; + } else { + // The right clipping boundary is outside of the content, but may affect + // the removed/injected portion of the range. + DWORD end_removed = end_original + mapped_range->removed; + if (clip_range.end() < end_removed) + mapped_range->removed = clip_range.end() - end_original; + + DWORD end_injected = end_original + mapped_range->injected; + if (clip_range.end() < end_injected) + mapped_range->injected = clip_range.end() - end_original; + } + + return; +} + +} // namespace + +int AddressRange::Compare(const AddressRange& rhs) const { + if (end() <= rhs.rva) + return -1; + if (rhs.end() <= rva) + return 1; + return 0; +} + +bool GetOmapDataAndDisableTranslation(IDiaSession* session, + OmapData* omap_data) { + assert(session != NULL); + assert(omap_data != NULL); + + CComPtr address_map; + if (FAILED(session->QueryInterface(&address_map))) { + fprintf(stderr, "IDiaSession::QueryInterface(IDiaAddressMap) failed\n"); + return false; + } + assert(address_map.p != NULL); + + BOOL omap_enabled = FALSE; + if (FAILED(address_map->get_addressMapEnabled(&omap_enabled))) { + fprintf(stderr, "IDiaAddressMap::get_addressMapEnabled failed\n"); + return false; + } + + if (!omap_enabled) { + // We indicate the non-presence of OMAP data by returning empty tables. + omap_data->omap_from.clear(); + omap_data->omap_to.clear(); + omap_data->length_original = 0; + return true; + } + + // OMAP data is present. Disable translation. + if (FAILED(address_map->put_addressMapEnabled(FALSE))) { + fprintf(stderr, "IDiaAddressMap::put_addressMapEnabled failed\n"); + return false; + } + + // Read the OMAP streams. + if (!FindAndLoadOmapTable(kOmapFromDebugStreamName, + session, + &omap_data->omap_from)) { + return false; + } + if (!FindAndLoadOmapTable(kOmapToDebugStreamName, + session, + &omap_data->omap_to)) { + return false; + } + + // Get the lengths of the address spaces. + if (!GetOriginalImageLength(session, &omap_data->length_original)) + return false; + + return true; +} + +void BuildImageMap(const OmapData& omap_data, ImageMap* image_map) { + assert(image_map != NULL); + + BuildMapping(omap_data, &image_map->mapping); + BuildEndpointIndexMap(image_map); +} + +void MapAddressRange(const ImageMap& image_map, + const AddressRange& original_range, + AddressRangeVector* mapped_ranges) { + assert(mapped_ranges != NULL); + + const Mapping& map = image_map.mapping; + + // Handle the trivial case of an empty image_map. This means that there is + // no transformation to be applied, and we can simply return the original + // range. + if (map.empty()) { + mapped_ranges->push_back(original_range); + return; + } + + // If we get a query of length 0 we need to handle it by using a non-zero + // query length. + AddressRange query_range(original_range); + if (query_range.length == 0) + query_range.length = 1; + + // Find the range of intervals that can potentially intersect our query range. + size_t imin = 0; + size_t imax = 0; + { + // The index of the earliest possible range that can affect is us done by + // searching through the secondary indexing structure. + const EndpointIndexMap& eim = image_map.endpoint_index_map; + EndpointIndex q1 = { query_range.rva, 0 }; + EndpointIndexMap::const_iterator it1 = std::lower_bound( + eim.begin(), eim.end(), q1, EndpointIndexLess); + if (it1 == eim.end()) { + imin = map.size(); + } else { + // Backup to find the interval that contains our query point. + if (it1 != eim.begin() && query_range.rva < it1->endpoint) + --it1; + imin = it1->index; + } + + // The first range that can't possibly intersect us is found by searching + // through the image map directly as it is already sorted by interval start + // point. + MappedRange q2 = { query_range.end(), 0 }; + Mapping::const_iterator it2 = std::lower_bound( + map.begin(), map.end(), q2, MappedRangeOriginalLess); + imax = it2 - map.begin(); + } + + // Find all intervals that intersect the query range. + Mapping temp_map; + for (size_t i = imin; i < imax; ++i) { + MappedRange mr = map[i]; + ClipMappedRangeOriginal(query_range, &mr); + if (mr.length + mr.injected > 0) + temp_map.push_back(mr); + } + + // If there are no intersecting ranges then the query range has been removed + // from the image in question. + if (temp_map.empty()) + return; + + // Sort based on transformed addresses. + std::sort(temp_map.begin(), temp_map.end(), MappedRangeMappedLess); + + // Zero-length queries can't actually be merged. We simply output the set of + // unique RVAs that correspond to the query RVA. + if (original_range.length == 0) { + mapped_ranges->push_back(AddressRange(temp_map[0].rva_transformed, 0)); + for (size_t i = 1; i < temp_map.size(); ++i) { + if (temp_map[i].rva_transformed > mapped_ranges->back().rva) + mapped_ranges->push_back(AddressRange(temp_map[i].rva_transformed, 0)); + } + return; + } + + // Merge any ranges that are consecutive in the mapped image. We merge over + // injected content if it makes ranges contiguous, but we ignore any injected + // content at the tail end of a range. This allows us to detect symbols that + // have been lengthened by injecting content in the middle. However, it + // misses the case where content has been injected at the head or the tail. + // The problem is that it doesn't know whether to attribute it to the + // preceding or following symbol. It is up to the author of the transform to + // output explicit OMAP info in these cases to ensure full coverage of the + // transformed address space. + DWORD rva_begin = temp_map[0].rva_transformed; + DWORD rva_cur_content = rva_begin + temp_map[0].length; + DWORD rva_cur_injected = rva_cur_content + temp_map[0].injected; + for (size_t i = 1; i < temp_map.size(); ++i) { + if (rva_cur_injected < temp_map[i].rva_transformed) { + // This marks the end of a continuous range in the image. Output the + // current range and start a new one. + if (rva_begin < rva_cur_content) { + mapped_ranges->push_back( + AddressRange(rva_begin, rva_cur_content - rva_begin)); + } + rva_begin = temp_map[i].rva_transformed; + } + + rva_cur_content = temp_map[i].rva_transformed + temp_map[i].length; + rva_cur_injected = rva_cur_content + temp_map[i].injected; + } + + // Output the range in progress. + if (rva_begin < rva_cur_content) { + mapped_ranges->push_back( + AddressRange(rva_begin, rva_cur_content - rva_begin)); + } + + return; +} + +} // namespace google_breakpad \ No newline at end of file diff --git a/src/common/windows/pdb_source_line_writer.cc b/src/common/windows/pdb_source_line_writer.cc index 9f4041d5..a3213dc3 100644 --- a/src/common/windows/pdb_source_line_writer.cc +++ b/src/common/windows/pdb_source_line_writer.cc @@ -496,6 +496,8 @@ bool PDBSourceLineWriter::PrintFunctions() { return true; } +#undef max + bool PDBSourceLineWriter::PrintFrameDataUsingPDB() { // It would be nice if it were possible to output frame data alongside the // associated function, as is done with line numbers, but the DIA API diff --git a/src/tools/windows/binaries/symupload.exe b/src/tools/windows/binaries/symupload.exe index 097e4291271bddf5064974f426dea7c21672fe8a..ba319b269f626c99920a67e5bb99de332ab56849 100644 GIT binary patch delta 93976 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 delta 105459 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�Gb`fI<{*P^c6Ft#&Ang*JzrZJ`r^o+&mgtwZ0Hho~twmpGMyb;rv zD>lz7xZ!xm@u6ckRh%$ETKrmyf$3SR!}f~pcN?b=Xp+x$QGTgBuN;l@Pf|aIs`L$J z1+Qw~)`sdLbqjSK-DkS4`dRuehTVn^#zu5u3e!l_OjEw;BU7_!wmHxIf%#)|h$X|a z5VM8O*4|d9^(pI4>j@94%qiOq+iv>_`)zw?N1P+U@qlBAV=e0PUdLg_ueh@lq#HX< zdB5@#l; zd!N>d*7Bfso3=_@jj^U#YtW6?J*=CJdDtS|)4FGLt936UPw(h<==OPNjV#^^Ee1+) z3skP!qS~t3hKbG&Rh8-xCOgMfwW?FNkG!Z7Rkiw4`Z|3O?!&?i(+n9Hj@^MqG=@jnN&Y9{>7fm9D^d=KmC~zKh zp`1UeWQba!j#bB@QYzJ2wNY(VJJreRRCSu#g^BAF^)$?`GS%7Y-2bO(^9NDoio*D0 zVzGq}EG*<p%skjHhLJOA#TI~EoeCTt-=h=Erakg$aW3kyMuEi9(6SePkr^oX5So{ z6P$OBvj#Zl7H2$|Co=*-h+9c3g)N3^aVu{Xt&&x-s+dL_RtrYpw!u+-0PM(`fHCLR z!V0W4)*U;r=E;h%D2uZsOR+Rl83$n%S&3CxmEFKIS}02QOk4vtg4s{moGsuZYqn)O zY$Q%B!lOLSk>8#iGL@7hmn225NE%qB5`$b5@0Wx8-U|-$hxZrRXf~FOgO{$ec~KN4 zQ4v-6VMBQCv;0%!UY4#teSVgI_~PA1TBCK^q#fF&y-z>>CI61UtBvvM5x?O*Jj)-# zz3uGvvupNnMZQ_JYF5qr{33t#4Zd9BogyB2QXoZyvBaGJlsSN2qTrSk3W1{lN{Z+I zE&u#ohr8V813uTHq;X8ih5j$ol0a>b@vx}Jfs&*ab*|j&$)_HO!$)%oI1z}FbR6FyLICgvg#E3p=vaFBH(u(Grh;&Q=xg~E!{aBiKh<3jj+ zpyAA!JAt!u)=qeQ%qM$UiiZ6~;w16EjE7iNBR8boA|28rccf1ykgmr!o_-<{EUTC) zLAF0;8nCWj#)l?MGSfFj2#}|J=6L4J3nhkJrO~o=wBi_KxmRK^Zh{J`gVy})Lw1!t zW)rHRmer=}LzY$$r36*m)Sx9=rVUh)Pao)t9_W!Kw3L?9ir|i}Hq<8COxtLZeyQgm zIGwY=48iIXbnsH&>3dx=QrK7+*vi$6y3sT`=PB~um>C;GLhD|c1+!)%^|3Fd{C_2| zgc-JbXK^0V5gkJeALx|M=p0+J1wvWV4c*cwfa@M%{i|vBkdPrnBn)87B6jqg^OT)F z&(nF-VCkIs8| " - L" [...]\n\n"); - wprintf(L"Timeout is in milliseconds, or can be 0 to be unlimited\n\n"); - wprintf(L"Example:\n\n\tsymupload.exe --timeout 0 chrome.dll " - L"http://no.free.symbol.server.for.you\n"); + wprintf(L"Usage:\n\n" + L" symupload [--timeout NN] [--product product_name] ^\n" + L" ^\n" + L" [...]\n\n"); + wprintf(L" - Timeout is in milliseconds, or can be 0 to be unlimited.\n"); + wprintf(L" - product_name is an HTTP-friendly product name. It must only\n" + L" contain an ascii subset: alphanumeric and punctuation.\n" + L" This string is case-sensitive.\n\n"); + wprintf(L"Example:\n\n" + L" symupload.exe --timeout 0 --product Chrome ^\n" + L" chrome.dll http://no.free.symbol.server.for.you\n"); exit(0); } int wmain(int argc, wchar_t *argv[]) { const wchar_t *module; + const wchar_t *product = nullptr; int timeout = -1; int currentarg = 1; - if (argc > 2) { - if (!wcscmp(L"--timeout", argv[1])) { - timeout = _wtoi(argv[2]); - currentarg = 3; + while (argc > currentarg + 1) { + if (!wcscmp(L"--timeout", argv[currentarg])) { + timeout = _wtoi(argv[currentarg + 1]); + currentarg += 2; + continue; } - } else { - printUsageAndExit(); + if (!wcscmp(L"--product", argv[currentarg])) { + product = argv[currentarg + 1]; + currentarg += 2; + continue; + } + break; } if (argc >= currentarg + 2) @@ -194,6 +207,17 @@ int wmain(int argc, wchar_t *argv[]) { parameters[L"debug_identifier"] = pdb_info.debug_identifier; parameters[L"os"] = L"windows"; // This version of symupload is Windows-only parameters[L"cpu"] = pdb_info.cpu; + + // Don't make a missing product name a hard error. Issue a warning and let + // the server decide whether to reject files without product name. + if (product) { + parameters[L"product"] = product; + } else { + fwprintf( + stderr, + L"Warning: No product name (flag --product) was specified for %s\n", + module); + } // Don't make a missing version a hard error. Issue a warning, and let the // server decide whether to reject files without versions. @@ -207,12 +231,15 @@ int wmain(int argc, wchar_t *argv[]) { bool success = true; while (currentarg < argc) { + int response_code; if (!HTTPUpload::SendRequest(argv[currentarg], parameters, symbol_file, L"symbol_file", timeout == -1 ? NULL : &timeout, - NULL, NULL)) { + nullptr, &response_code)) { success = false; - fwprintf(stderr, L"Symbol file upload to %s failed\n", argv[currentarg]); + fwprintf(stderr, + L"Symbol file upload to %s failed. Response code = %ld\n", + argv[currentarg], response_code); } currentarg++; } diff --git a/src/tools/windows/symupload/symupload.vcproj b/src/tools/windows/symupload/symupload.vcproj deleted file mode 100644 index 50f50b7c..00000000 --- a/src/tools/windows/symupload/symupload.vcproj +++ /dev/null @@ -1,251 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -