Coverage for /Syzygy/pe/dia_util.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
77.8%70900.C++source

Line-by-line coverage:

   1    :  // Copyright 2012 Google Inc.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  
  15    :  #include "syzygy/pe/dia_util.h"
  16    :  
  17    :  #include <diacreate.h>
  18    :  
  19    :  #include "base/logging.h"
  20    :  #include "base/win/scoped_bstr.h"
  21    :  #include "base/win/scoped_comptr.h"
  22    :  #include "sawbuck/common/com_utils.h"
  23    :  
  24    :  namespace pe {
  25    :  
  26    :  using base::win::ScopedBstr;
  27    :  using base::win::ScopedComPtr;
  28    :  
  29    :  #if _MSC_VER == 1500
  30    :      const wchar_t kDiaDllName[] = L"msdia90.dll";
  31    :  #elif _MSC_VER == 1600
  32    :      const wchar_t kDiaDllName[] = L"msdia100.dll";
  33    :  #else
  34    :  #error Cannot determine DIA DLL name.
  35    :  #endif
  36    :  
  37    :  const wchar_t kFixupDiaDebugStreamName[] = L"FIXUP";
  38    :  const wchar_t kOmapToDiaDebugStreamName[] = L"OMAPTO";
  39    :  const wchar_t kOmapFromDiaDebugStreamName[] = L"OMAPFROM";
  40    :  
  41  E :  bool CreateDiaSource(IDiaDataSource** created_source) {
  42  E :    DCHECK(created_source != NULL);
  43    :  
  44  E :    *created_source = NULL;
  45    :  
  46  E :    ScopedComPtr<IDiaDataSource> dia_source;
  47  E :    HRESULT hr1 = dia_source.CreateInstance(CLSID_DiaSource);
  48  E :    if (SUCCEEDED(hr1)) {
  49  E :      *created_source = dia_source.Detach();
  50  E :      return true;
  51    :    }
  52    :  
  53    :    HRESULT hr2 = NoRegCoCreate(kDiaDllName,
  54    :                                CLSID_DiaSource,
  55    :                                IID_IDiaDataSource,
  56  E :                                reinterpret_cast<void**>(&dia_source));
  57  E :    if (SUCCEEDED(hr2)) {
  58  E :      *created_source = dia_source.Detach();
  59  E :      return true;
  60    :    }
  61    :  
  62  i :    LOG(ERROR) << "Failed to create DiaDataSource.";
  63  i :    LOG(ERROR) << "  CreateInstance failed with: " << com::LogHr(hr1);
  64  i :    LOG(ERROR) << "  NoRegCoCreate failed with: " << com::LogHr(hr2);
  65    :  
  66  i :    return false;
  67  E :  }
  68    :  
  69    :  bool CreateDiaSession(const FilePath& file,
  70    :                        IDiaDataSource* dia_source,
  71  E :                        IDiaSession** dia_session) {
  72  E :    DCHECK(dia_source != NULL);
  73  E :    DCHECK(dia_session != NULL);
  74    :  
  75  E :    *dia_session = NULL;
  76    :  
  77  E :    HRESULT hr = E_FAIL;
  78    :  
  79  E :    if (file.Extension() == L".pdb") {
  80  E :      hr = dia_source->loadDataFromPdb(file.value().c_str());
  81  E :    } else {
  82  E :      hr = dia_source->loadDataForExe(file.value().c_str(), NULL, NULL);
  83    :    }
  84    :  
  85  E :    if (FAILED(hr)) {
  86  i :      LOG(ERROR) << "Failed to load DIA data for \"" << file.value() << "\": "
  87    :                 << com::LogHr(hr) << ".";
  88  i :      return false;
  89    :    }
  90    :  
  91  E :    ScopedComPtr<IDiaSession> session;
  92  E :    hr = dia_source->openSession(session.Receive());
  93  E :    if (FAILED(hr)) {
  94  i :      LOG(ERROR) << "Failed to open DIA session for \"" << file.value() << "\" : "
  95    :                 << com::LogHr(hr) << ".";
  96  i :      return false;
  97    :    }
  98    :  
  99  E :    *dia_session = session.Detach();
 100    :  
 101  E :    return true;
 102  E :  }
 103    :  
 104    :  SearchResult FindDiaTable(const IID& iid,
 105    :                            IDiaSession* dia_session,
 106  E :                            void** out_table) {
 107  E :    DCHECK(dia_session != NULL);
 108  E :    DCHECK(out_table != NULL);
 109    :  
 110  E :    *out_table = NULL;
 111    :  
 112    :    // Get the table enumerator.
 113  E :    base::win::ScopedComPtr<IDiaEnumTables> enum_tables;
 114  E :    HRESULT hr = dia_session->getEnumTables(enum_tables.Receive());
 115  E :    if (FAILED(hr)) {
 116  i :      LOG(ERROR) << "Failed to get DIA table enumerator: "
 117    :                 << com::LogHr(hr) << ".";
 118  i :      return kSearchErrored;
 119    :    }
 120    :  
 121    :    // Iterate through the tables.
 122  E :    while (true) {
 123  E :      base::win::ScopedComPtr<IDiaTable> table;
 124  E :      ULONG fetched = 0;
 125  E :      hr = enum_tables->Next(1, table.Receive(), &fetched);
 126  E :      if (FAILED(hr)) {
 127  i :        LOG(ERROR) << "Failed to get DIA table: "
 128    :                   << com::LogHr(hr) << ".";
 129  i :        return kSearchErrored;
 130    :      }
 131  E :      if (fetched == 0)
 132  i :        break;
 133    :  
 134  E :      hr = table.QueryInterface(iid, out_table);
 135  E :      if (SUCCEEDED(hr))
 136  E :        return kSearchSucceeded;
 137  E :    }
 138    :  
 139    :    // The search completed, even though we didn't find what we were looking for.
 140  i :    return kSearchFailed;
 141  E :  }
 142    :  
 143    :  SearchResult FindDiaDebugStream(const wchar_t* name,
 144    :                                  IDiaSession* dia_session,
 145  E :                                  IDiaEnumDebugStreamData** dia_debug_stream) {
 146  E :    DCHECK(name != NULL);
 147  E :    DCHECK(dia_session != NULL);
 148  E :    DCHECK(dia_debug_stream != NULL);
 149    :  
 150  E :    *dia_debug_stream = NULL;
 151    :  
 152  E :    HRESULT hr = E_FAIL;
 153  E :    ScopedComPtr<IDiaEnumDebugStreams> debug_streams;
 154  E :    if (FAILED(hr = dia_session->getEnumDebugStreams(debug_streams.Receive()))) {
 155  i :      LOG(ERROR) << "Unable to get debug streams: " << com::LogHr(hr) << ".";
 156  i :      return kSearchErrored;
 157    :    }
 158    :  
 159    :    // Iterate through the debug streams.
 160  E :    while (true) {
 161  E :      ScopedComPtr<IDiaEnumDebugStreamData> debug_stream;
 162  E :      ULONG count = 0;
 163  E :      HRESULT hr = debug_streams->Next(1, debug_stream.Receive(), &count);
 164  E :      if (FAILED(hr) || (hr != S_FALSE && count != 1)) {
 165  i :        LOG(ERROR) << "Unable to load debug stream: "
 166    :                   << com::LogHr(hr) << ".";
 167  i :        return kSearchErrored;
 168  E :      } else if (hr == S_FALSE) {
 169    :        // No more records.
 170  E :        break;
 171    :      }
 172    :  
 173  E :      ScopedBstr stream_name;
 174  E :      if (FAILED(hr = debug_stream->get_name(stream_name.Receive()))) {
 175  i :        LOG(ERROR) << "Unable to get debug stream name: "
 176    :                   << com::LogHr(hr) << ".";
 177  i :        return kSearchErrored;
 178    :      }
 179    :  
 180    :      // Found the stream?
 181  E :      if (wcscmp(com::ToString(stream_name), name) == 0) {
 182  E :        *dia_debug_stream = debug_stream.Detach();
 183  E :        return kSearchSucceeded;
 184    :      }
 185  E :    }
 186    :  
 187  E :    return kSearchFailed;
 188  E :  }
 189    :  
 190    :  }  // namespace pe

Coverage information generated Thu Sep 06 11:30:46 2012.