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 : #include "syzygy/refinery/symbols/symbol_provider_util.h"
16 :
17 : #include <string>
18 :
19 : #include "base/environment.h"
20 : #include "base/numerics/safe_conversions.h"
21 : #include "base/strings/string16.h"
22 : #include "base/strings/utf_string_conversions.h"
23 : #include "syzygy/pe/find.h"
24 :
25 : namespace refinery {
26 :
27 : namespace {
28 :
29 : // TODO(manzagop): this probably exists somewhere?
30 E : bool GetEnvVar(const char* name, base::string16* value) {
31 E : DCHECK(name != NULL);
32 E : DCHECK(value != NULL);
33 E : value->clear();
34 :
35 E : scoped_ptr<base::Environment> env(base::Environment::Create());
36 E : if (env.get() == NULL) {
37 i : LOG(ERROR) << "base::Environment::Create returned NULL.";
38 i : return false;
39 : }
40 :
41 : // If this fails, the environment variable simply does not exist.
42 E : std::string var;
43 E : if (!env->GetVar(name, &var))
44 E : return true;
45 :
46 E : if (!base::UTF8ToUTF16(var.c_str(), var.size(), value)) {
47 i : LOG(ERROR) << "base::UTF8ToUTF16(\"" << var << "\" failed.";
48 i : return false;
49 : }
50 :
51 E : return true;
52 E : }
53 :
54 : } // namespace
55 :
56 : bool GetPdbPath(const pe::PEFile::Signature& signature,
57 E : base::FilePath* pdb_path) {
58 E : DCHECK(pdb_path);
59 :
60 : // Get the module's path.
61 E : base::string16 symbol_paths;
62 E : GetEnvVar("_NT_SYMBOL_PATH", &symbol_paths);
63 E : base::FilePath module_local_path;
64 : if (!pe::FindModuleBySignature(signature, symbol_paths, &module_local_path) ||
65 E : module_local_path.empty()) {
66 i : LOG(ERROR) << "Failed to find module (name, size, timestamp): "
67 : << signature.path << ", " << signature.module_size << ", "
68 : << signature.module_time_date_stamp;
69 i : return false;
70 : }
71 :
72 : // Get the pdb's path.
73 : if (!pe::FindPdbForModule(module_local_path, symbol_paths, pdb_path) ||
74 E : pdb_path->empty()) {
75 i : LOG(ERROR) << "Failed to find pdb for module " << signature.path;
76 i : return false;
77 : }
78 :
79 E : return true;
80 E : }
81 :
82 : } // namespace refinery
|