1 : // Copyright 2015 Google Inc. All Rights Reserved.
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 : #ifndef SYZYGY_REFINERY_SYMBOLS_DIA_SYMBOL_PROVIDER_H_
16 : #define SYZYGY_REFINERY_SYMBOLS_DIA_SYMBOL_PROVIDER_H_
17 :
18 : #include <dia2.h>
19 :
20 : #include "base/macros.h"
21 : #include "base/containers/hash_tables.h"
22 : #include "base/memory/ref_counted.h"
23 : #include "base/strings/string16.h"
24 : #include "base/win/scoped_comptr.h"
25 : #include "syzygy/pe/pe_file.h"
26 : #include "syzygy/refinery/core/address.h"
27 :
28 m : namespace refinery {
29 :
30 : // The DiaSymbolProvider provides symbol information via the DIA interfaces.
31 : // @note It is *not* safe to interleave access to a session in the context of
32 : // different process states, as the session's load address may be different.
33 : // @note use of virtual is to allow mocking.
34 : // TODO(manzagop): this class should share an interface with SymbolProvider, for
35 : // providing type repositories. This would enable replacing one implementation
36 : // for the other and possibly sharing some implementation.
37 m : class DiaSymbolProvider : public base::RefCounted<DiaSymbolProvider> {
38 m : public:
39 m : DiaSymbolProvider();
40 m : virtual ~DiaSymbolProvider();
41 :
42 : // Retrieves or creates an IDiaSession for the module corresponding to @p
43 : // signature.
44 : // @note on success, the session's load address is not set.
45 : // @param signature the signature of the module for which to get a session.
46 : // @param session on success, returns a session for the module. On failure,
47 : // contains nullptr.
48 : // @returns true on success, false on failure.
49 m : virtual bool FindOrCreateDiaSession(
50 m : const pe::PEFile::Signature& signature,
51 m : base::win::ScopedComPtr<IDiaSession>* session);
52 :
53 : // Retrieves the relative virtual addresses of all virtual function tables in
54 : // the module identified by @p signature.
55 : // @param signature the signature of the module.
56 : // @param vftable_rvas on success contains zero or more addresses.
57 : // @returns true on success, false on failure.
58 m : virtual bool GetVFTableRVAs(const pe::PEFile::Signature& signature,
59 m : base::hash_set<Address>* vftable_rvas);
60 :
61 m : private:
62 : // TODO(manzagop): this function is duplicated in SymbolProvider. It should
63 : // likely be extracted to a cross-platform Signature class.
64 m : static void GetCacheKey(const pe::PEFile::Signature& signature,
65 m : base::string16* cache_key);
66 :
67 m : bool GetOrLoad(const pe::PEFile::Signature& signature,
68 m : base::win::ScopedComPtr<IDiaDataSource>* source,
69 m : base::win::ScopedComPtr<IDiaSession>* session);
70 :
71 : // Caching for dia pdb file sources and sessions (matching entries). The cache
72 : // key is "<basename>:<size>:<checksum>:<timestamp>". The cache may contain
73 : // negative entries (indicating a failed attempt at creating a session) in the
74 : // form of null pointers.
75 : // The caches must be consistent: the presence of a valid source implies the
76 : // presence of a valid session, and vice versa.
77 m : base::hash_map<base::string16, base::win::ScopedComPtr<IDiaDataSource>>
78 m : pdb_sources_;
79 m : base::hash_map<base::string16, base::win::ScopedComPtr<IDiaSession>>
80 m : pdb_sessions_;
81 :
82 m : DISALLOW_COPY_AND_ASSIGN(DiaSymbolProvider);
83 m : };
84 :
85 m : } // namespace refinery
86 :
87 : #endif // SYZYGY_REFINERY_SYMBOLS_DIA_SYMBOL_PROVIDER_H_
|