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